结构内部的联合 - 如何做指定的初始化程序?

hua*_*xin 2 c++ struct

我已经在union初始化中读取了struct,但它没有解决我的问题

在我的遗留代码中,我有大量的struct-with-union

typedef struct st 
{
    union
    {
        struct
        {
            uint8    sign ;
            uint8    cells;    
        }s;
        int    data;
    }u;
    int   extra;
} st;
Run Code Online (Sandbox Code Playgroud)

在C下,编译如下:

static const st someval = {
    .sign = 0, .cells ={ 0 },  
    .cells = { 11 }
};
Run Code Online (Sandbox Code Playgroud)

有没有办法最小化更改编译方法(或代码),使其在g ++下编译?

eer*_*ika 5

static const st someval = {
     .sign = 0, .cells ={ 0 },  
//              ^
     .cells = { 11 } };
//   ^
Run Code Online (Sandbox Code Playgroud)

你初始化cells两次,这使得这在C++中不正确.

此外,既不是sign也不cell是直接成员st.该声明也在C中形成.

下面将正确使用C++ 20中的指定初始化程序(未来的C++标准,它被提议为该语言引入指定的初始化程序):

static const st someval = {
     .u{.s{.sign = 0, .cells = 11}},
     // NOTE .extra left zero-initialized
};
Run Code Online (Sandbox Code Playgroud)

或者以下,这在C++ 20和C中都是正确的:

static const st someval = {
     .u = {.s = {.sign = 0, .cells = 11}},
};
Run Code Online (Sandbox Code Playgroud)

但是,当前的C++标准没有指定的初始值设定项.您可以编写一个创建本地非const零初始化st对象的函数,然后使用成员访问器初始化您要初始化的特定成员,然后返回该对象.然后,您可以st通过调用该函数来初始化const 对象.该初始化函数可能在其他任何地方都没用,因此您可能希望使用lambda来避免不必要地污染命名空间:

static const st someval = []() {
    st o {};
    o.u.s.sign = 0;
    o.u.s.cells = 11;
    return o;
}();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,C11 [§6.7.9初始化19](https://port70.net/~nsz/c/c11/n1570.html#6.7.91919)说:_初始化应在初始化程序列表顺序中进行,每个初始化程序都提供对于覆盖同一子对象的任何先前列出的初始化程序的特定子对象; _并且脚注151表示子对象的_Any初始化程序被覆盖,因此不用于初始化该子对象可能根本不会被评估.所以,双 - `.cells`的初始化是没有意义的,但是允许的. (3认同)
  • @JonathanLeffler确实在C中,但不是在C++中.我添加了澄清资格. (2认同)