大小小于 int 的位域是否应该作为积分提升的主题?

假设我有以下 struct:

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

我感兴趣的是表达式a + b 的类型.虽然从技术上讲位域具有小于 int 的类型",因此可能应该发生积分提升,然后结果是 int 就像它恰好在 gcc 和 clang 中一样.

What interests me is the type of expression a + b. While technically bit-fields have "type" with size less than int so integral promotion probably should happen and then result is int like it happens to be in gcc and clang.

但是由于不可能提取位字段本身的确切类型,并且它总是会被推导出它的大"类型(即 unsigned int 在这种情况下)是否正确积分推广应该发生吗?因为我们实际上不能谈论位域的确切类型和它们的大小,除非它们被推导出为 unsigned int 在这种情况下不应该发生积分提升.

But since it's impossible to extract the exact type of bit-field itself and it will always be deduced to be its "big" type (i.e. unsigned int in this case) is it correct that integral promotion should happen? Because we can't actually talk about exact types and their sizes for bit-fields except them being deduced as unsigned int in which case integral promotion shouldn't happen.

(我的问题再次源于这样一个事实,即 MSVC 恰好认为 unsigned int 是这种表达式的类型)

(Once again my question stems from the fact that MSVC happens to think that unsigned int is type of such expression)

推荐答案

如果我们去draft C++ 标准:N4140 部分 5 它说:

If we go to the draft C++ standard: N4140 section 5 it says:

许多需要算术或运算操作数的二元运算符枚举类型导致转换并产生类似的结果类型大大地.目的是产生一个通用类型,它也是结果.这种模式称为通常的算术转换,定义如下

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows

并且以下要点适用:

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

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

and section 4.5 which says (emphasis mine):

整数位域 (9.6) 的纯右值可以转换为类型 int 的纯右值如果 int 可以表示位域; 否则,如果是无符号的,则可以转换为无符号整数int 可以表示位域的所有值.如果位域是更大,没有积分促销适用于它.如果位域有枚举类型,它被视为该类型的任何其他值推广目的.

A prvalue for an integral bit-field (9.6) can be converted to a prvalue of type int if int can represent all the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes.

所以gcc和clang是正确的,ab应该提升为int.

So gcc and clang are correct, a and b should be promoted to int.

相关文章