C++匿名结构体

13

我使用以下联合来简化字节、半字节和位操作:

union Byte
{
  struct {
    unsigned int bit_0: 1;
    unsigned int bit_1: 1;
    unsigned int bit_2: 1;
    unsigned int bit_3: 1;
    unsigned int bit_4: 1;
    unsigned int bit_5: 1;
    unsigned int bit_6: 1;
    unsigned int bit_7: 1;
  };

  struct {
    unsigned int nibble_0: 4;
    unsigned int nibble_1: 4;
  };

  unsigned char byte;
};

它的功能很好,但也会生成以下警告:

warning: ISO C++ prohibits anonymous structs [-pedantic]

好的,知道了。但是...如何从g++输出中消除此警告?是否有可能编写类似于此联合体而不出现此问题?


2
为什么不直接给你的结构体命名呢? - Luchian Grigore
4
您试图在有效的 C++ 范围内无法完成您想要做的事情。它可能会运作,但这将是未定义行为。 - Kerrek SB
我可以给它命名,例如结构体“nibbles”,并将其作为联合的一个字段。但是那样我就必须访问它Byte.nibbles.nibble_0。这样使用起来不太好看。 - Dejwi
1
或者,Byte.nibble.n0Byte.nibble._<0>()Byte.nibble._[0]get<0>(Byte.nibble),因为你可以在访问时DRY并且删除重复的nibble,并且可能会在一些商标中进行装饰。 - Yakk - Adam Nevraumont
就像@KerrekSB所说的那样。例如,GCC将通过字节序反转字段顺序,使位7显示为位0。您最好使用bool bit(unsigned int n) const { return byte & (1 << n); } - Simon Richter
1个回答

12

gcc编译器选项-fms-extensions将允许非标准匿名结构体而不会发出警告。

(该选项启用它认为的“Microsoft扩展”)

您还可以在有效的C++中使用此约定来实现相同的效果。

union Byte
{
  struct bits_type {
    unsigned int _0: 1;
    unsigned int _1: 1;
    unsigned int _2: 1;
    unsigned int _3: 1;
    unsigned int _4: 1;
    unsigned int _5: 1;
    unsigned int _6: 1;
    unsigned int _7: 1;
  } bit;
  struct nibbles_type {
    unsigned int _0: 4;
    unsigned int _1: 4;
  } nibble;
  unsigned char byte;
};

有了这个,您的非标准byte.nibble_0就变成了合法的byte.nibble._0


3
你关于前导下划线是正确的。在全局命名空间中以下划线开头的名称被保留给实现。以下划线开头并后跟大写字母或包含双下划线的名称也被保留给实现。- 参见17.6.4.3.2(C++11) - Captain Obvlious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接