How does type conversion and integer promotion work for stdint.h?

294 views Asked by At

In C, I understand type conversions, integer promotion, casting, etc. for standard types, but how do the stdint.h types factor into this?

For type rankings, the rules state:

  • No two signed integer types shall have the same rank, even if they have the same representation.
  • The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.

So assuming an int is 32 bits, does this mean int > int32_t = uint32_t > short int in the rankings?

Also, are the stdint.h types also subject to integer promotion? For example if I try to add a signed char to a uint32_t, they will both get promoted to unsigned ints?

2

There are 2 answers

9
David Grayson On BEST ANSWER

To answer your first question: no. Since int32_t is usually defined with a typedef like this

typedef int int32_t;

it is the same as int and will have the same rank as int.

To answer the second question: yes. Integer promotion still applies. The types defined in stdint.h behave just like the types they are aliases of.

By the way, to be more confident in how your compiler behaves, you can test all of these things in your compiler by writing invalid code like this and carefully looking at the error message, which will (if you have a good compiler) reveal the type of the expression on the right hand side:

void * x = (signed char)-1 + (uint32_t)0;
10
Vlad from Moscow On

According to the C Standard

— The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.

The exact integer types for 2's complement representation are defined as tyoedef aliases of standard integer types.

From the C Standard (7.20.1.1 Exact-width integer types)

  1. ...and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.

So this relational when the type int has 32 bits (for 2's complement representation)

int > int32_t = uint32_t > short int

is correct except that the relation int > int32_t provided that the type int32_t is an alias name for the type int introduced by a typedef declaration..

Also, are the stdint.h types also subject to integer promotion? For example if I try to add a signed char to a uint32_t, they will both get promoted to unsigned ints?

Here the object of the type unsigned char is promoted to the type int and the object of the type uint32_t is promoted to the type unsigned int (provided that int has 32-bits) due to the integer promotions

From the C Standard

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.

And then the object of the type int is converted to the type unsigned int due to the usual arithmetic conversions.

From the C Standard (6.3.1.8 Usual arithmetic conversions)

Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

Pay attention to then the name uint32_t can be an alias for the type unsigned int introduced by a typedef declaration. In this case uint32_t is the same type as unsigned int.