clang 与 gcc 中空结构的默认初始化程序
Default Initializer of empty struct in clang vs gcc
以下代码使用 GCC 的某些版本和 Clang 的某些版本编译(请参阅下面的版本)。
struct my_struct {};
int main(int argc, char** argv) {
const my_struct my_object;
return 0;
};
编译:g++ clang_error.cpp
和 clang++ clang_error.cpp
。我在 4.8.4 有 g++,在 3.6.0.
有 clang++
错误信息是:
clang_error.cpp:7:19: error: default initialization of an object of const type 'const my_struct' without a user-provided default constructor
const my_struct my_object;
^
clang_error.cpp:7:28: note: add an explicit initializer to initialize 'my_object'
const my_struct my_object;
^
= {}
1 error generated.
受影响的版本
使用 Compiler Explorer here,我可以看到 GCC 高达 4.5.4 受到影响。 Clang 影响到 3.9.0。
问题
我的问题是:C++ 标准对此有何规定?理想情况下,我会关心 C++14,但我在那里并不挑剔。
上面的示例代码是否符合标准?
到目前为止我发现了什么
我在 C++14 的 Draft N3797 中找到了以下内容。
§ 7.1.6.1 The cv-qualifiers [dcl.type.cv]
2 [ Note: Declaring a variable const can affect its linkage (7.1.1) and its usability in constant expressions (5.19).
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. — end note ]
§ 8.5
7 To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and
the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an
ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
— if T is an array type, each element is default-initialized;
— otherwise, no initialization is performed.
What does the C++ standard say about this?
Is the above example code standard-conformant?
在C++14中,是non-conformant:
n4431 (2015) standard draft [dcl.init] / 7:
If a program calls for the default initialization of an object of a const-qualified type
T
,
T
shall be a class type
with a user-provided default constructor.
my_struct
没有 user-provided 默认构造函数,所以你不应该 default-initialize.
然而,一些较新的编译器似乎选择放宽规则,可能是因为它受到缺陷报告的影响:DR 253。
即将出台的标准改变了措辞:
Current (2017) standard draft [dcl.init] / 7:
A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
(7.4) each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
(7.5) if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
(7.6) if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and
(7.7) each potentially constructed base class of T is const-default-constructible.
If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.
这个措辞对我来说有点模棱两可,但我认为由于 my_struct
没有违反 7.4 的成员(并且不是联合,所以 7.5 不适用,没有联合成员所以 7.6 不适用不适用且没有基础,因此 7.7 不适用),它是 const-default-constructible 因此该示例将是一致的。
以下代码使用 GCC 的某些版本和 Clang 的某些版本编译(请参阅下面的版本)。
struct my_struct {};
int main(int argc, char** argv) {
const my_struct my_object;
return 0;
};
编译:g++ clang_error.cpp
和 clang++ clang_error.cpp
。我在 4.8.4 有 g++,在 3.6.0.
错误信息是:
clang_error.cpp:7:19: error: default initialization of an object of const type 'const my_struct' without a user-provided default constructor
const my_struct my_object;
^
clang_error.cpp:7:28: note: add an explicit initializer to initialize 'my_object'
const my_struct my_object;
^
= {}
1 error generated.
受影响的版本
使用 Compiler Explorer here,我可以看到 GCC 高达 4.5.4 受到影响。 Clang 影响到 3.9.0。
问题
我的问题是:C++ 标准对此有何规定?理想情况下,我会关心 C++14,但我在那里并不挑剔。
上面的示例代码是否符合标准?
到目前为止我发现了什么
我在 C++14 的 Draft N3797 中找到了以下内容。
§ 7.1.6.1 The cv-qualifiers [dcl.type.cv]
2 [ Note: Declaring a variable const can affect its linkage (7.1.1) and its usability in constant expressions (5.19). 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. — end note ]§ 8.5
7 To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
— if T is an array type, each element is default-initialized;
— otherwise, no initialization is performed.
What does the C++ standard say about this?
Is the above example code standard-conformant?
在C++14中,是non-conformant:
n4431 (2015) standard draft [dcl.init] / 7:
If a program calls for the default initialization of an object of a const-qualified type T , T shall be a class type with a user-provided default constructor.
my_struct
没有 user-provided 默认构造函数,所以你不应该 default-initialize.
然而,一些较新的编译器似乎选择放宽规则,可能是因为它受到缺陷报告的影响:DR 253。
即将出台的标准改变了措辞:
Current (2017) standard draft [dcl.init] / 7:
A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
(7.4) each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
(7.5) if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
(7.6) if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and
(7.7) each potentially constructed base class of T is const-default-constructible.
If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.
这个措辞对我来说有点模棱两可,但我认为由于 my_struct
没有违反 7.4 的成员(并且不是联合,所以 7.5 不适用,没有联合成员所以 7.6 不适用不适用且没有基础,因此 7.7 不适用),它是 const-default-constructible 因此该示例将是一致的。