【问题标题】:Is the "Type of bit field too small for number of bits" error part of the C++ standard?C++ 标准的“位域类型对于位数来说太小”错误部分吗?
【发布时间】:2016-09-09 15:59:30
【问题描述】:

以下代码在 Visual Studio 2008 中生成 MSVS Compiler Error C2034

struct TestStruct {
    unsigned short var1 : 7;
    unsigned short      : 9;
    bool var2           : 1;
    bool                : 15; // C2034
};
错误 C2034: 'TestStruct::': 位字段类型对于位数而言太小

但是,下面的代码编译成功,这看起来有点傻,因为我认为编译器可以自动完成:

struct TestStruct {
    unsigned short var1 : 7;
    unsigned short      : 9;
    bool var2           : 1;
    bool                : 7;
    bool                : 8;
};

但是,两个代码 sn-ps 都在我的 Linux GCC 编译器上编译。根据 C++ 标准,一个编译器是否比另一个更正确?如果有,是哪一个,为什么?

【问题讨论】:

  • 通常情况下,MSVS 几乎总是错误的。 Clang 3.4.1 也编译成功了。
  • 您为什么希望编译器在您背后默默地为您重写代码?您明确要求 bool 类型的 15 位字段,这是不可能的。它应该如何知道您实际上想要一个 bool 类型的 8 位字段,而不是创建一个 long 类型的 15 位字段或其他? (GCC 和 ICC 对此发出警告。如果我知道正确的开关,Clang 也可能会这样做。你的问题就是,为什么 MSVC 将其视为 错误?)
  • @CodyGray 如果不可能,为什么 Linux 上的 GCC 让我这样做?而且类型不重要,它们只是对齐部分,不是吗?
  • @Rakete1111 除了在这种情况下 g++ 也会抱怨。 coliru.stacked-crooked.com/a/c95cb2b1e77dbdb5(这是一个警告,但仍然)
  • 如果允许编译器做出假设,这当然不是不可能。很少有。但是,让编译器重新解释您在背后编写的代码,这违反了最小意外原则。

标签: c++ language-lawyer bit-fields


【解决方案1】:

是的,这是 MSVS 中的一个错误。该标准在 [class.bit]/1

中声明

[...]整数常量表达式的值可能大于位域类型的对象表示(3.9)中的位数;在这种情况下,额外的位被用作填充位并且不参与位域的值表示(3.9)。[...]

所以编译器应该添加额外的填充,并且只让你的位数等于CHAR_BIT * sizeof(bit_field_underlying_type)

【讨论】:

  • 我真的不会称这是一个错误。肯定是MSVS不符合标准,但显然是要生成错误消息。所以“非标准行为”可能是一个更好的描述。
  • @lcs 我会说不符合标准是一个错误。
  • @SebastianLenartowicz 当 gcc 和 clang 没有时,它确实捕获了 this ;)
  • @lcs:在/Za mode 中,不符合是一个错误。在/Ze模式下,只是故意的偏差。
  • 我已经发送了feedback to MSVC关于这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
相关资源
最近更新 更多