2014-04-10 13 views
13

xem xét sau mã ví dụ:initialisation của biến tĩnh với chính nó

#include <iostream> 

static int bar = bar; 

int main() 
{ 
    int foo = foo; 
    std::cout << "foo = " << foo << std::endl; 
    std::cout << "bar = " << bar << std::endl; 
} 

tôi nhận được sau cảnh báo trình biên dịch:

main.cpp: In function 'int main()': 
main.cpp:7:15: warning: 'foo' is used uninitialized in this function [-Wuninitialized] 
    int foo = foo; 
      ^

Output:

foo = 0 
bar = 0 

tôi mong đợi cảnh báo này như foo là được sử dụng unitialised. Thay vì 0, 'foo' có thể là bất cứ thứ gì. Tự gán không được xác định.

Nhưng tại sao việc tự gán 'thanh' không được cảnh báo? Đây có phải là sự phân công của 'bar' được xác định hoặc hành vi không xác định và tại sao?

Tôi biết, các biến tĩnh của kiểu dữ liệu elementar được khởi tạo bằng '0' nhưng trong trường hợp này, biến 'thanh' được sử dụng trong quá trình khởi tạo. Tôi tự hỏi, nếu điều này được xác định hành vi và '0' là đầu ra dự kiến. (Mà sẽ giải thích, rằng không có cảnh báo trình biên dịch xảy ra).

Link to Live example

+0

Khởi tạo tĩnh có nhiều hơn một giai đoạn. – chris

+0

Có thể do các biến tĩnh trong phạm vi toàn cục luôn luôn được khởi tạo bằng 0, do đó trình biên dịch biết 'bar' là có hiệu quả' 0' trước khi gán. –

+1

@ FrédéricHamidi: Lưu ý rằng chúng không được khởi tạo bằng 0, nhưng được xây dựng mặc định. Điều đó tạo nên sự khác biệt cho cấu trúc/lớp học! – anderas

Trả lời

14

Tôi tin rằng một phần của tiêu chuẩn có liên quan đến câu hỏi của bạn (§3.6.2/2):

biến với thời gian tĩnh lưu trữ (3.7.1) hoặc thời gian lưu trữ chủ đề (3.7.2) sẽ là zero-khởi (8,5) trước khi bất kỳ khởi khác diễn ra. [...]

Vì vậy, trong trường hợp này, ngay cả trước khi trình biên dịch nhìn vào định nghĩa của bạn về bar, nó đã không khởi tạo nó.

Vì nó được chỉ định thêm một chút trong tiêu chuẩn, sẽ có hai giai đoạn để khởi tạo biến tĩnh (nhấn mạnh mỏ).

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. Khởi tạo tĩnh sẽ được thực hiện trước khi bất kỳ khởi tạo động nào diễn ra.