Visual C++初始化与gcc和clang不一致

Visual C++ initialization inconsistence with gcc and clang

本文关键字:clang 不一致 gcc C++ 初始化 Visual      更新时间:2023-10-16

以下代码打印用vc++编译的0和用g++clang++编译的1

#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++也开始打印1

在阅读标准(C++11 n3485(时,12.6.2/9声明:

如果给定的非静态数据成员同时具有brace-or-equal-initializermem-initializer,则执行由mem-initializer指定的初始化,并且忽略该非静态数据会员的brace-or-equal-initializer

因此,问题变成了default,即隐式定义的构造函数是否包含mem-initializer

12.1/6节规定:

隐式定义的默认构造函数执行类的初始化集,该初始化集将由用户为没有ctor-initializer(12.6.2(和空compound-statement的类编写的默认构造函数来执行。

这意味着隐式生成的(默认(构造函数没有mem-initializers,实际上应该使用类内初始值设定项(上面引用的brace-or-equal-initializer(。

微软风投在这里错了(真的,这并不奇怪(。

这不是一个答案,而是一个需要代码的注释。

以下更清楚地说明了编译器的差异,我认为:

#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++使用类中指定的初始值设定项,而MSVC使用s声明中指定的初始化项。在我看来,这似乎是g++的一个问题。但我不确定:唯一确定的是两者都不可能是对的。