大小小于 int 的位域是否应该作为整体提升的主题?
Should bit-fields less than int in size be the subject of integral promotion?
假设我有以下 struct
:
struct A
{
unsigned int a : 1;
unsigned int b : 1;
};
我感兴趣的是表达式的类型a + b
。虽然从技术上讲,位域 "type" 的大小小于 int
,因此可能应该进行积分提升,然后结果是 int
,就像它恰好在 gcc 和 clang 中一样。
但是由于不可能提取位域本身的确切类型,并且它总是被推断为它的 "big" 类型(即本例中的 unsigned int
)积分是否正确晋升应该发生?因为我们实际上不能谈论位域的确切类型和它们的大小,除非它们被推断为 unsigned int
在这种情况下不应该发生整数提升。
(我的问题再次源于 MSVC 碰巧认为 unsigned int
是此类表达式的类型)
如果我们转到 draft C++ standard: N4140 部分 5
它说:
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
以下要点适用:
- Otherwise, the integral promotions (4.5) shall be performed on both operands.61 Then the following rules shall be applied to the promoted
operands:
和第 4.5 节说(强调我的):
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是正确的,a
和b
应该提升为int。
假设我有以下 struct
:
struct A
{
unsigned int a : 1;
unsigned int b : 1;
};
我感兴趣的是表达式的类型a + b
。虽然从技术上讲,位域 "type" 的大小小于 int
,因此可能应该进行积分提升,然后结果是 int
,就像它恰好在 gcc 和 clang 中一样。
但是由于不可能提取位域本身的确切类型,并且它总是被推断为它的 "big" 类型(即本例中的 unsigned int
)积分是否正确晋升应该发生?因为我们实际上不能谈论位域的确切类型和它们的大小,除非它们被推断为 unsigned int
在这种情况下不应该发生整数提升。
(我的问题再次源于 MSVC 碰巧认为 unsigned int
是此类表达式的类型)
如果我们转到 draft C++ standard: N4140 部分 5
它说:
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
以下要点适用:
- Otherwise, the integral promotions (4.5) shall be performed on both operands.61 Then the following rules shall be applied to the promoted operands:
和第 4.5 节说(强调我的):
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是正确的,a
和b
应该提升为int。