2016-10-19 17 views
19

Tôi vô tình tạo lỗi trong chương trình bằng cách tự tham chiếu trong một mảng. Đây là một chương trình demo rất đơn giản tương tự như trong khái niệm:C++ tự tham chiếu mảng?

#include <iostream> 
using namespace std; 

int kTest[] = { 
    kTest[0] 
}; 

int main() { 
    cout << kTest[0] << endl; 
} 

Tôi rất ngạc nhiên khi nhận được lỗi trình biên dịch hoặc thậm chí là cảnh báo về mã này! Trong trường hợp của tôi nó kết thúc sản xuất đầu ra không thể đoán trước. Là nó truy cập bộ nhớ rác?

Tôi đã tò mò về những điều kiện này sẽ có đầu ra tốt (nếu bao giờ!).

Chỉnh sửa: Có khác biệt gì nếu kTeststatic? Điều gì về const? Cả hai?

+0

hmm. toàn cầu 'int' là không khởi tạo vì vậy tôi tự hỏi nếu vì nó là hợp pháp. – NathanOliver

+0

Trong trường hợp tiêu chuẩn ngôn ngữ cho phép loại cú pháp này. –

+2

Nó không khác với ['int x = x;'] (http://stackoverflow.com/questions/14935722/does-initialization-entail-lvalue-to-rvalue-conversion-is-int-xx-ub) . –

Trả lời

15
int kTest[] = { 
    kTest[0] 
}; 

là tương tự, nếu không muốn nói chính xác giống như

int x = x; 

Đó sẽ là hành vi không xác định, nếu công bố tại địa phương trong một hàm.

Dường như được xác định rõ khi kTest là biến toàn cục. Xem the other answer để biết thêm chi tiết.

+1

Điều này không nên là một ý kiến ​​phải không? Hoặc là UB của nó không được định nghĩa theo tiêu chuẩn? – Carcigenicate

+0

Có thể không xác định được không? Tôi đoán nó tương tự như thế này: 'int x; x = x; '. –

+0

@Carcigenicate, tôi thấy trong tiêu chuẩn C++ 11 trong đó 'int x = x;' được thảo luận nhưng tôi không thể tìm thấy bất kỳ điều gì nói về tình hình của OP. –

8

Tôi không chắc chắn điều này là không xác định. Trích dẫn từ hiện tại draft:

[basic.start.static]/3

Nếu khởi tạo liên tục không được thực hiện, một biến với thời gian lưu trữ tĩnh ([basic.stc.static]) hoặc chủ đề thời gian lưu trữ ([basic.stc.thread]) là zero-initialized ([dcl.init]). Cùng nhau, không khởi tạo và khởi tạo liên tục được gọi là khởi tạo tĩnh ; tất cả khởi tạo khác là khởi tạo động. Khởi tạo tĩnh phải được thực hiện trước khi bất kỳ khởi tạo động nào diễn ra.

Với tôi, có vẻ như kTest đã không được khởi tạo khi khởi động động bắt đầu, vì vậy nó có thể được xác định để khởi tạo 0.

+0

Giải thích của bạn có ý nghĩa.'g ++ 'không phàn nàn về' int x = x; 'khi được xác định trên toàn cầu nhưng bị khiếu nại khi được định nghĩa trong một hàm. –

+1

Tại sao bạn cho rằng khởi tạo toàn cục của OP là động? Nếu tôi có 'static int a [] = {1};' được khởi tạo tĩnh. 'a [0]' không được khởi tạo thành 0 (tĩnh) và sau đó được khởi tạo lại thành 1 (động). –

+0

@ PaulJ.Lucas: * Cùng nhau, không khởi tạo và khởi tạo liên tục được gọi là khởi tạo tĩnh; tất cả các khởi tạo khác là khởi tạo động. * – krzaq