What is the purpose of "Macros for whole constants of minimum width"

In C99, Section 7.18.4.1, “Macros for Constants with the Minimum Width,” some macros defined as [U]INT[N]_C(x) , for targeted integers for the smallest data types, where N = 8, 16, 32 , 64. Why are these macros how can I use L, UL, LL or ULL modifiers? For example, when I want to use at least 32 bits of an unsigned constant integer, I can simply write 42UL instead of UINT32_C(42) . Since a long data type has a width of at least 32 bits, it is also portable.

So what is the purpose of these macros?

+6
source share
3 answers

You need them in those places where you want to make sure that they do not get too wide.

 #define myConstant UINT32_C(42) 

and later

 printf( "%" PRId32 " is %s\n", (hasproperty ? toto : myConstant), "rich"); 

here, if the constant is UL , the expression can be ulong , and the variational function can put on the stack a 64-bit value that printf will not correctly interpret.

+7
source

They use the smallest integer type with a width of at least N, so UINT32_C(42) equivalent to only 42UL on systems where int less than 32 bits. On systems where int is 32 bits or more, UINT32_C(42) equivalent to 42U . You can even imagine a system where short is 32 bits wide, in which case UINT32_C(42) would be equivalent to (unsigned short)42 .

EDIT: @obareey It seems that most, if not all, implementations of the standard library do not match this part of the standard, possibly because it is not possible. [ glibc commit 2841 ] [ glibc commit b7398be5 ]

+3
source

Macros can essentially add a suffix with integer constants, such as L , LL , U , UL , o UL to their argument, which basically makes them almost equivalent to the corresponding cast, except that the suffix will never be omitted.

for example, UINT32_C(42000000000) (42 billion) on the LLP64 architecture will turn into 42000000000U , which will be of type UL , subject to the rules described here . The corresponding cast, on the other hand ( (uint32_t)42000000000 ), truncates it to uint32_t ( unsigned int on LLP64).

I can’t come up with a good use case, but I suppose that it can be used in some general macro accounts that require at least X bits, but don’t want to delete extra bits if the user goes through something larger.

0
source

Source: https://habr.com/ru/post/944218/


All Articles