只是为 MSVC 和 G++ 添加一些关于该主题的额外信息,并准确地呼应@Charles Bailey 和@René Richter 所说的话;它可以接受 C++03 和 C++11,但根据编译器的年龄和实现状态,如果有的话,你会得到不同的错误。
实际上,我为 EDG、MSVC2008 和 G++ 尝试了 Dinkum's online test compilers,并且都编译了您提供的示例,但没有编译我在下面提供的示例。
简而言之,完全初始化 带有 const 成员的结构 将在 MSVC2008 和 G++4.5 上成功编译,但是在经过测试的编译器中没有一个可以编译 strong> “部分初始化”(或部分聚合初始化) POD 结构,即使这在 C++ 标准中也是允许的——我什至联系了一些 G++ 错误维护人员,以确保我正确阅读了该标准并且他们确认它甚至可以在当前的 C++03 编译器中工作。
您可以在GNU Bugzilla 和Microsoft's Visual Studio help pages 上看到与此相关的错误,它实际上是从这个other stackoverflow article titles "why do I get this warnings in Visual Studio when building a struct? 链接的,它也与Microsoft's Error C3852 as a known behavior of even MSVC2010 相关
// All sections refer to Draft C++03 (brackets refer to draft C++11)
//
// 3.9.3 CV (const/volatile) definition as "const data-type [= optional init]"
// 7.1.5.1/1 The cv-qualifiers [ 7.1.6.1/1 in C++11 ]
// "init-declarator-list of the declaration shall not be empty"
const int constval = 10 ;
// HOWEVER:
// 7.1.5.1/2 The cv-qualifiers [ 7.1.6.1 in C++11 ]
// [Note: as described in 8.5, the definition of an object or subobject
// of const-qualified type must specify an initializer or be subject to
// default-initialization. ]
// 8.5 Initializers
// 8.5/9 (C++11 8.5/11)
// Otherwise, if no initializer is specified for a non-static
// object, the object and its sub-objects, if any, have an indeterminate
// initial value(*90); if the object or any of its sub-objects are of
// const-qualified type, the program is ill-formed.
//
// *90: This does not apply to aggregate objects with automatic storage
// duration initialized with an incomplete brace-enclosed initializer list
// see 8.5.1.
// [ C++11 this sub-clause has been removed, however the list-initializer section
// pretty much covers the same topic - see 8.5.1/7 below ]
//
// 8.5.1 Aggregate definition
// 8.5.1/7 (C++11 8.5.1/7)
// If there are fewer initializers in the list than there are members in the
// aggregate, then each member not explicitly initialized shall be
// value-initialized (8.5).
//
// 8.5/5 value initialization
// if T is a class type (clause 9) with a user-declared constructor
// (12.1), then the default constructor for T is called (and the
// initialization is ill-formed if T has no accessible default constructor)
// ...
// otherwise, the object is zero-initialized
//
// 8.5/5 zero initialization
// if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
//
// POD type
struct A {
int n ;
const int m ; // "const" causes failure in MSVC to make default constructor
} ;
// Example of non-POD
struct B {
int bbb ;
B(){}
} ;
#include <stdio.h>
int main() {
// C++03/11 ill formed code, fails as expected
const int c0 ; // per 7.1.5.1 "not allowed to be default init"
// OK
const int c = *new int ; // A default initialized constant
const int c2 = *new int(); // A zero-init, above is DEFAULT-INIT
printf( "c: %i\n", c ) ; // should be an undef-value
printf( "c2: %i\n", c2 ) ; // should be 0
// OK ; Array example making sure it works
const int aa[5] = {}; // all items value->zero-initialized per the above 8.5.1/7
printf( "aa: %i %i %i\n", aa[0], aa[2], aa[4] ) ;
// C++03/11 ill formed code, no initializer (G++/MSVC should fail)
A a0 ; // Correct error - no default constructor or initializer (8.5/9)
// C++03/11 correctly formed code, full initializer list (G++/MSVC should pass)
A a1 = {1,2}; // Explicit initialization OK, G++/MSVC pass
// C++03/11 correctly formed code; copy initialized from a value-initialized A()
A a2 = A(); // G++ OK, MSVC FAIL
// C++03/11 correctly formed code; aggregate partial intializer (8.5.1/7 agg list init)
A a3 = {}; // G++/MSVC FAIL
A a4{}; // C++11 only - doesnt work in G++ (didnt try MSVC2010)
printf( "a0.m=%i\n", a0.m ) ; // a0 should not exist due compile errors
printf( "a1.m=%i\n", a1.m ) ; // a1.m should be 2
printf( "a2.m=%i\n", a2.m ) ; // a2.m should be 0
printf( "a3.m=%i\n", a3.m ) ; // a3.m should be 0
// C++03/11 correctly formed code; user-default constructor supplied.
const B bee1 ; // Default constructor marks bbb as "initialized"
const B bee2 = {} ; // CORRECTLY flagged error; init of non-aggregate
printf( "%i\n", bee1.bbb ) ;
}