给出示例代码:
struct S {
char data[5];
int a;
};
在Microsoft Visual Studio中运行“运行代码分析”时,它会警告初始化所有变量。
现在我知道您可以通过多种方法来执行此操作,创建默认的构造函数,例如:
S() :
data{0},
a{0} {
}
这使警告消失了。但是,如果您不想手动创建默认构造函数,那该怎么办。
类似:
struct S {
char data[5];
int a = 0;
};
摆脱了a
的警告,但没有摆脱data
的警告,尽管您可以通过以下方式添加{}
来解决此问题:char data[5]{};
似乎可以进行代码分析快乐。
这让我开始思考,您也可以像a
一样初始化int a{0};
所以我的问题是,这些都有效吗?哪个更可取?
旁注:我注意到std::array
有_Ty _Elems[_Size];
,它永远不会在任何地方初始化,也没有{}
之后的东西,我假设他们只是忽略了这个警告?还是他们在做我不注意“修复”警告的事情?
还想添加以下代码: #包括 #include
template<class T, std::size_t N>
struct static_vector {
typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N] = {0};
T& operator[](std::size_t pos) {
return *std::launder(reinterpret_cast<T*>(&data[pos]));
}
};
int main(int argc, char**) {
static_vector<int, 10> s;
s[0] = argc;
return s[0];
}
gcc9.1 -std=c++17 -Wall
下的不产生警告,
而clang8.0 -std=c++17 -Wall
下的相同代码给了我
warning: suggest braces around initialization of subobject [-Wmissing-braces]
typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N] = {0};
^
{}
我看到可以将其设置为= {};
来对其进行修复,只是想知道为什么一个编译器会在另一个不生成警告时发出警告?要指定哪一个?
答案 0 :(得分:3)
在C ++中,对于每个声明器,初始化器可以是以下之一:
1. ( expression-list )
2. = expression
3. { initializer-list }
这些的描述如下:
究竟哪种类型的初始化实际上取决于上下文。要在类中初始化数据成员,我个人会使用braced initializer
在类初始化中首选,因为在这种情况下,我们不必编写用户定义的default constructor
,
班级成员
可以使用member initializer list或default member initializer初始化非静态数据成员。
您可能需要使用:
struct S {
char data[5] = {0}; //initialize by zero
int a = 0;
};
或也给它们提供不同的值
struct S {
char data[5] = {0,1,2,3,4};
int a = 0;
};
有关更多信息,请参见Initialization
答案 1 :(得分:1)
CPPCoreGuidelines对此的指导原则是:Don’t define a default constructor that only initializes data members; use in-class member initializers instead
所以您可以这样做:
struct S {
char data[5] = {0};
int a = 0;
};
关于与std::array
相关的缺乏警告的其他问题,海湾合作委员会(GCC)有一条说明:
通常会抑制系统标头中的警告,因为它们通常不会指示实际问题,只会使编译器的输出难以阅读。
我相信MSVC也是如此。