Wrong definition of UINT16_C in arm-none-eabi-gcc?

Viewed 130

I noticed that arm-none-eabi-gcc 10.2 defines the macros UINTN_C in the following way (compiling with -mcpu=cortex-m7 -std=c99 -g3 -O0):

#define UINT32_C(x) __UINT32_C(x)  
#define UINT16_C(x) __UINT16_C(x) 

Then

#define __UINT32_C(c) c ## UL
#define __UINT16_C(c) c

The C99 standard (7.18.4.1 p2) says that:

The macro UINTN_C(value) shall expand to an unsigned integer constant with the specified value and type uint_leastN_t.

The 32 bits version is indeed expanding to an unsigned 32 bits representation (uint_least32_t is unsigned long on this CPU).

However the 16 bits version expands to a signed representation: UINT16_C(1) expands to 1 which is of type int.

Isn't it contradictory to the standard ? Is there an option of gcc that would fix that ?

Why not doing something like #define __UINT16_C(c) ((uint_least16_t)(c)) ?

1 Answers

C doesn't recognize the notion of a numeric literal whose type is smaller than int and unsigned int. On a platform where int is 32 bits, the expression (uint16_t)123 would behave as type signed int as a result of integer promotion, and it would be somewhat illogical for an expression containing a numeric literal of supposed type uint16_t to behave in a manner inconsistent with the way any other expression of that type would be processed.

Related