9

假设我有以下内容struct

struct A
{
    unsigned int a : 1;
    unsigned int b : 1;
};

我感兴趣的是表达的类型a + b。虽然从技术上讲,位域的“类型”的大小小于int可能应该发生整体提升,然后结果int就像它恰好在 gcc 和 clang 中一样。

但是由于不可能提取位域本身的确切类型并且它总是被推断为它的“大”类型(即unsigned int在这种情况下),所以应该进行整体提升是否正确?因为我们实际上不能谈论位域的确切类型和它们的大小,除非它们被推断为unsigned int在这种情况下不应该发生积分提升。

(我的问题再次源于 MSVC 碰巧认为这unsigned int是这种表达的类型)

4

1 回答 1

6

如果我们查看C++ 标准草案:N4140部分5,它会说:

许多期望算术或枚举类型的操作数的二元运算符会以类似的方式导致转换和产生结果类型。目的是产生一个通用类型,这也是结果的类型。这种模式称为通常的算术转换,其定义如下

以下项目符号适用:

  • 否则,应在两个操作数上执行积分提升 (4.5)。61 然后应将以下规则应用于提升的操作数:

和第 4.5 节说(强调我的):

如果 int 可以表示位域的所有值,则整数位域 (9.6) 的纯右值可以转换为int 类型的纯右值;否则,如果 unsigned int 可以表示位域的所有值,则可以将其转换为 unsigned int。如果位域更大,则不会对其应用积分提升。如果位字段具有枚举类型,则出于提升目的,将其视为该类型的任何其他值。

所以gcc和clang是正确的,a应该b提升为int。

于 2015-09-11T17:36:39.327 回答