Visual C++ 初始化与 gcc 和 clang 不一致
Visual C++ initialization inconsistence with gcc and clang
下面这段代码prints 0
compiled with vc++ and prints 1
compiled with g++ or clang++:
#include <iostream>
#include <vector>
struct S
{
S() = default;
std::vector<int> v{0};
};
int main()
{
std::vector<S> s{{}};
std::cout << s.front().v.size() << std::endl;
}
是否是 vc++ 中的错误?
如果提供了用户定义的构造函数(S() {};
而不是 S() = default;
)vc++ starts to print 1
, too。
这不是答案,而是需要代码的评论。
我认为以下更清楚地说明了编译器的差异:
#include <iostream>
#include <vector>
struct S
{
S() = default;
std::vector<int> v = std::vector<int>(13);
};
int main()
{
std::vector<S> s{{}};
std::cout << s.front().v.size() << std::endl;
}
此处 g++ MinGW 5.1.0 报告 13 个项目,而 MSVC 2015 更新 2 报告 0 个项目。
即g++ 使用 class 中指定的初始值设定项,而 MSVC 使用 s
声明中指定的初始值设定项。对我来说,这看起来像是 g++ 的问题。但我不确定:唯一确定的是两者不可能都是对的。
在阅读标准 (C++11 n3485) 时,12.6.2/9
指出:
If a given non-static data member has both a brace-or-equal-initializer
and a mem-initializer
, the initialization specified by the mem-initializer
is performed, and the non-static data member’s brace-or-equal-initializer
is ignored.
所以问题就变成了default
,即隐式定义的构造函数是否包含mem-initializer
。
第 12.1/6
节指出:
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer
(12.6.2) and an empty compound-statement
.
这意味着隐式生成的(默认)构造函数没有 mem-initializer
并且确实应该使用 in-class 初始化程序(上面引用中的 brace-or-equal-initializer
)。
MSVC 在这里是错误的(这并不奇怪,真的)。
下面这段代码prints 0
compiled with vc++ and prints 1
compiled with g++ or clang++:
#include <iostream>
#include <vector>
struct S
{
S() = default;
std::vector<int> v{0};
};
int main()
{
std::vector<S> s{{}};
std::cout << s.front().v.size() << std::endl;
}
是否是 vc++ 中的错误?
如果提供了用户定义的构造函数(S() {};
而不是 S() = default;
)vc++ starts to print 1
, too。
这不是答案,而是需要代码的评论。
我认为以下更清楚地说明了编译器的差异:
#include <iostream>
#include <vector>
struct S
{
S() = default;
std::vector<int> v = std::vector<int>(13);
};
int main()
{
std::vector<S> s{{}};
std::cout << s.front().v.size() << std::endl;
}
此处 g++ MinGW 5.1.0 报告 13 个项目,而 MSVC 2015 更新 2 报告 0 个项目。
即g++ 使用 class 中指定的初始值设定项,而 MSVC 使用 s
声明中指定的初始值设定项。对我来说,这看起来像是 g++ 的问题。但我不确定:唯一确定的是两者不可能都是对的。
在阅读标准 (C++11 n3485) 时,12.6.2/9
指出:
If a given non-static data member has both a
brace-or-equal-initializer
and amem-initializer
, the initialization specified by themem-initializer
is performed, and the non-static data member’sbrace-or-equal-initializer
is ignored.
所以问题就变成了default
,即隐式定义的构造函数是否包含mem-initializer
。
第 12.1/6
节指出:
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no
ctor-initializer
(12.6.2) and an emptycompound-statement
.
这意味着隐式生成的(默认)构造函数没有 mem-initializer
并且确实应该使用 in-class 初始化程序(上面引用中的 brace-or-equal-initializer
)。
MSVC 在这里是错误的(这并不奇怪,真的)。