1

According to the standard C11 p6.3.1.1

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions.

I'm curious in what situation will a value be promoted to an unsigned int? Types like short int definitely fit for a signed int, Even if I defined a 31bits in a struct as bit field, it still fit a signed int.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • There is no default casting of integers to unsigned int, if you define a type as int it will stay an int. – SPlatten Aug 15 '19 at 08:00
  • @pmg I don't think there's a promotion happens in you example, you example is defined as the type of a constant in standard 6.4.4.1 Integer constants –  Aug 15 '19 at 08:05
  • `unsigned short` if it won't fit `int`. – Weather Vane Aug 15 '19 at 08:49
  • @WeatherVane when will `unsigned short` not fit `int`? `unsigned short int` is way shorter than `signed int` even though the later one has a signed bit. –  Aug 15 '19 at 08:51
  • When it's 32 bits. `unsigned short` has a *minimum* of 16 bits. – Weather Vane Aug 15 '19 at 08:52
  • `unsigned short int is way shorter` - may be, not is. – KamilCuk Aug 15 '19 at 08:52
  • Similarly with `long` (although there aren't integer conversions here). On my machine it is 32 bits (the minimum) but on others it is 64 bits. – Weather Vane Aug 15 '19 at 08:53
  • so it's so called promotion but no bit width actually changed in this case? –  Aug 15 '19 at 08:57
  • Explained in the answer here [Implicit type promotion rules](https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules). Scroll down to integer promotions. – Lundin Aug 15 '19 at 09:33
  • On 8 and 16 bit systems, `unsigned short` won't fit inside `int` and will therefore get converted to `unsigned int`, which is also 16 bit and has 100% identical representation as `unsigned short`. The "conversion" is mostly academic. – Lundin Aug 15 '19 at 09:42

1 Answers1

1

The case is when the maximum value of an integer type with rank lower then int is promoted. So it happens on unsigned short, unsigned char and char when it is unsigned on a platform.

When USHRT_MAX is greater then INT_MAX, then unsigned short is implicitly promoted to unsigned int type. Similar, when UCHAR_MAX is greater then INT_MAX, then unsigned char is promoted to unsigned int type. And, when char on a platform is unsigned and UCHAR_MAX is greater then INT_MAX, the same happens to char.

_Bool will always be converted to int. Although the number of bits in a _Bool is at least CHAR_BIT, the width of a _Bool is 1 bit, so int will always be able to represent all _Bool values . ( I am not sure if the "as restricted by the width" part of the standard applies only to bit-fields or to all types that undergo conversion. There is a comma before the "for a bit-field" part. )

P.S. The article is about C++, but I would like to recomment it: No-one knows the type of char + char. It touches the exact problem - char + char can be int or unsigned int, depending on if char is unsigned and if char can hold larger values then int.

Even if I defined a 31bits in a struct as bit field, it still fit a signed int.

Not always. A range of values that can be represented with a bitfield struct member that has width of 31 bits may not fit in an signed int variable. Simply, signed int may have 30 or less bits on a specific architecture. signed int is required to represent values at least between -32767 to +32767. So 2^31 may not fit into signed int.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • 1
    It is more helpful to ignore fictional computers. On real-world computers, `char + char` is always `int`. I believe that is even true for the various exotic, obsolete DSPs with 16 bit bytes. – Lundin Aug 15 '19 at 09:39