Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should bit-fields less than int in size be the subject of integral promotion?

Let's say I have following struct:

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

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.

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.

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

like image 863
Predelnik Avatar asked Sep 11 '15 17:09

Predelnik


People also ask

What is integral data promotion?

Some data types like char , short int take less number of bytes than int, these data types are automatically promoted to int or unsigned int when an operation is performed on them. This is called integer promotion.

What is integer promotion?

Integer promotion is the implicit conversion of a value of any integer type with rank less or equal to rank of int or of a bit field of type _Bool, int, signed int, unsigned int, to the value of type int or unsigned int.

What is bit field integer?

Bit fields can be used to reduce memory consumption when a program requires a number of integer variables which always will have low values. For example, in many systems storing an integer value requires two bytes (16-bits) of memory; sometimes the values to be stored actually need only one or two bits.


1 Answers

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

and the following bullet applies:

  • Otherwise, the integral promotions (4.5) shall be performed on both operands.61 Then the following rules shall be applied to the promoted operands:

and section 4.5 which says (emphasis mine):

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.

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

like image 134
Shafik Yaghmour Avatar answered Oct 05 '22 01:10

Shafik Yaghmour