C ++内联初始化成员变量的正确方法 [英] C++ proper way to inline initialize member variables

查看:216
本文介绍了C ++内联初始化成员变量的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出示例代码:

  struct S {
char data [5];
int a;
};

在Microsoft Visual Studio中运行运行代码分析时,它会警告初始化所有变量。 / p>

现在,我知道您可以通过多种方式执行此操作,创建默认的构造函数,例如:

  S():
数据{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
#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下的相同代码17 -Wall 给我:

 警告:建议在子对象初始化周围使用括号[-Wmissing-braces] 
类型名称std :: aligned_storage< sizeof (T),alignof(T)> :: type data [N] = {0};
^
{}

我看到可以将其设置为 = {}; 可以解决此问题,只是想知道为什么一个编译器会在另一个不生成警告时发出警告?

解决方案

CPPCoreGuidelines 关于此状态:不要定义仅初始化数据成员的默认构造函数;而是使用类内成员初始化程序



所以您可以这样做:

  struct S {
char data [5] = {0};
int a = 0;
};

关于您与 std相关的缺少警告的其他问题:数组,GCC的注释中指出:


通常禁止来自系统标题的警告,前提是它们通常并不表示真正的问题,只会使编译器的输出更难阅读。


我相信MSVC确实如此。好吧。


Given the example code:

struct S {
    char data[5];
    int a;
};

When running the "Run code analysis" in Microsoft Visual Studio, It warns to initialize all variables.

Now I know you can do this a number of ways, create a default constructor such as:

S() :
    data{0},
    a{0} {
}

That makes the warning go away. But what if you don't want to manually create the default constructor.

something like:

struct S {
    char data[5];
    int a = 0;
};

gets rid of the warning for a but not data, though you can fix that by adding {} after like so: char data[5]{}; this seems to make the code analysis happy.

That got me thinking, you can also initialize a like int a{0};

So my question is, are these all valid, and which is preferred?

Side note: I noticed std::array has _Ty _Elems[_Size]; which it never initializes anywhere, nor does it have {} after it, I'm assuming they just ignore this warning? Or are they doing something I'm not noticing to "fix" the warning?

Also wanted to add that this code: #include #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];
}

under gcc9.1 -std=c++17 -Wall produces no warnings, yet the same code under clang8.0 -std=c++17 -Wall gives me:

warning: suggest braces around initialization of subobject [-Wmissing-braces]
        typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N] = {0};
                                                                              ^
                                                                              {}

I see that I can set it to = {}; which fixes it, just wondering why one compiler would produce a warning when the other doesn't? Which one is to spec?

解决方案

The guideline from CPPCoreGuidelines on this states: Don’t define a default constructor that only initializes data members; use in-class member initializers instead

So you can just do:

struct S {
    char data[5] = {0};
    int a = 0;
};

As to your other question about the lack of warning related to std::array, GCC has a note which states:

Warnings from system headers are normally suppressed, on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read.

I believe this would be true of MSVC as well.

这篇关于C ++内联初始化成员变量的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆