2011-11-11 28 views
14

này biên dịch hoàn toàn tốt đẹp với các trình biên dịch MSVC hiện tại:uninitialized const

struct Foo 
{ 
} const foo; 

Tuy nhiên, nó không biên dịch với g hiện ++ biên dịch:

error: uninitialized const 'foo' [-fpermissive] 
note: 'const struct Foo' has no user-provided default constructor 

Nếu tôi cung cấp một constructor mặc định bản thân mình, nó hoạt động:

struct Foo 
{ 
    Foo() {} 
} const foo; 

Đây có phải là trường hợp khác của MSVC quá dễ chấp nhận hay là quá mức nghiêm ngặt ở đây?

+0

Câu hỏi tuyệt vời Mr Overflow. –

+0

Bản sao: http://stackoverflow.com/questions/5335836/why-a-const-object-of-an-empty-class-cant-be-created http://stackoverflow.com/questions/7411515/why- do-c-require-a-user-cung cấp-mặc định-constructor-to-default-construct-a trong số những thứ khác. – GManNickG

+0

Tôi không thể sao chép điều này trên GCC 4.6.1, với bất kỳ tùy chọn phương ngữ nào. Nó chỉ hoạt động nếu tôi cài đặt biến thành viên (như 'int a;') và lỗi chính xác hơn nhiều: ''const struct Foo' không có hàm tạo mặc định do người dùng cung cấp và hàm tạo ngầm được định nghĩa không khởi tạo 'int Foo :: a'' –

Trả lời

13

C++ 03 Tiêu chuẩn:

8,5 [dcl.init] đoạn 9

Nếu không khởi tạo được quy định cho một đối tượng, và đối tượng là (có thể cv loại không thuộc loại POD (hoặc loại của chúng), đối tượng sẽ được khởi tạo mặc định; nếu đối tượng thuộc loại có đủ điều kiện, kiểu lớp cơ bản sẽ có một hàm tạo mặc định do người dùng khai báo.

Từ phía trên, lỗi trong gcc có vẻ hợp lệ hoàn toàn.

+7

+1 cho Mr I-a-Hash-Bảng-of-the-Standard :-) –

1

Tôi không biết từ ngữ chính xác của tiêu chuẩn, nhưng lỗi trong g ++ có vẻ khá hợp lý hơn so với tùy chọn không nói bất cứ điều gì. Xem xét việc này:

struct X { 
    int value; 
}; 
const X constant; // constant.value is undefined 

Không trong trường hợp của một người dùng cung cấp constructor mặc định (ngay cả khi nó không làm gì) trình biên dịch sẽ gọi constructor đó và đối tượng sẽ được khởi (bởi bất cứ điều gì định nghĩa của khởi bạn đã triển khai trong hàm tạo của bạn).

3

[2003: 8.5/9]:Nếu không khởi tạo được quy định cho một đối tượng, và đối tượng là (có thể cv-đủ điều kiện) phi POD lớp loại (hoặc mảng đó), đối tượng chịu mặc định khởi tạo ; nếu đối tượng có loại 01 loại hợp lệ là , loại lớp cơ bản sẽ có một hàm tạo mặc định là do người dùng khai báo. Nếu không, nếu không có bộ khởi tạo là được chỉ định cho đối tượng không phải là đối tượng, đối tượng và đối tượng con của nó, nếu bất kỳ, có giá trị ban đầu không xác định; nếu đối tượng hoặc bất kỳ các đối tượng con của nó là loại có đủ điều kiện, chương trình không đúng định dạng.

Và:

[n3290: 8.5/11]:Nếu không khởi tạo được quy định cho một đối tượng, đối tượng là mặc định-khởi tạo; nếu không khởi tạo được được thực hiện, một đối tượng có thời lượng lưu trữ tự động hoặc động có giá trị không xác định là . [Lưu ý: Đối tượng có bộ nhớ tĩnh hoặc luồng thời lượng không được khởi tạo, xem 3.6.2._ End note_]

[n3290: 8.5/6]: Để mặc định-khởi một đối tượng kiểu T có nghĩa là:

  • nếu T là một (có thể cv-đủ điều kiện) kiểu lớp (khoản 9), các nhà xây dựng mặc định cho T được gọi (và khởi tạo không đúng định dạng nếu T không có hàm tạo mặc định có thể truy cập);
  • nếu T là loại mảng, mỗi phần tử được khởi tạo mặc định;
  • nếu không, không khởi tạo được thực hiện.

Nếu một chương trình đòi hỏi phải khởi tạo mặc định của một đối tượng của một const đủ tiêu chuẩn loại T, T phải là một kiểu lớp với một constructor mặc định dùng cung cấp.

Vì vậy, MSVC thuận tiện hơn cả hai tiêu chuẩn bắt buộc.

Các vấn đề liên quan