Reputation: 309
In C99 standard Section 7.18.4.1 "Macros for minimum-width integer constants", some macros defined as [U]INT[N]_C(x)
for casting constant integers to least data types where N = 8, 16, 32, 64. Why are these macros defined since I can use L, UL, LL or ULL modifiers instead? For example, when I want to use at least 32 bits unsigned constant integer, I can simply write 42UL
instead of UINT32_C(42)
. Since long data type is at least 32 bits wide it is also portable.
So, what is the purpose of these macros?
Upvotes: 7
Views: 1143
Reputation: 60117
The macros essentially possibly add an integer constant suffix 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 won't ever downcast.
E.g.,
UINT32_C(42000000000)
(42 billion) on an LLP64 architecture will turn into 42000000000U
, which will have type UL
subject to the rules explained here. The corresponding cast, on the other hand ((uint32_t)42000000000
), would truncate it down to uint32_t
(unsigned int
on LLP64).
I can't think of a good use case, but I imagine it could be usable in some generic bit-twiddling macros that need at least X bits to work, but don't want to remove any extra bits if the user passes in something bigger.
Upvotes: 0
Reputation: 14714
They use the smallest integer type with a width of at least N, so UINT32_C(42)
is only equivalent to 42UL
on systems where int
is smaller than 32 bits. On systems where int
is 32 bits or greater, UINT32_C(42)
is equivalent to 42U
. You could even imagine a system where a 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 comply with this part of the standard, perhaps because it is impossible. [glibc bug 2841] [glibc commit b7398be5]
Upvotes: 3
Reputation: 78963
You'd need them in places where you want to make sure that they don't become too wide
#define myConstant UINT32_C(42)
and later
printf( "%" PRId32 " is %s\n", (hasproperty ? toto : myConstant), "rich");
here, if the constant would be UL
the expression might be ulong
and the variadic function could put a 64bit value on the stack that would be misinterpreted by printf
.
Upvotes: 7