On 2026-02-25 David Grayson wrote:
> On Wed, Feb 25, 2026 at 12:47 AM LIU Hao <[email protected]> wrote:
>
> > > +#define UINT32_MAX 0xffffffff
> > > +#define UINT_MAX 0xffffffff
> >
> > ... why no `u` here?
> >
>
> For all these macros, I decided to use no suffix if possible. A
> suffix is not needed here because in the C99 specification the type
> of an unsuffixed hexadecimal constant will be the first type in this
> list that can represent it:
>
> 1. int
> 2. unsigned int
> 3. long int
> 4. unsigned long int
> 5. long long int
> 6. unsigned long long int
>
> So in the systems we are targeting, 0xffffffff will be an unsigned
> int since it cannot be represented by an int. If you want a suffix
> for clarity, I can add one, but I don't think it's necessary.
> However, I do use ull instead of ll in macros like ULONGLONG_MAX
> because I don't want readers to see ll and assume the type is simply
> long long.
All this is correct except in the preprocessor. Since C99, preprocessor
treats integers as if they were intmax_t or uintmax_t. See C99 6.10.1p3
or C11 6.10.1p4. The footnote in both standards explains it well:
Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is
0xFFFF, the constant 0x8000 is signed and positive within a #if
expression even though it would be unsigned in translation phase 7.
Try:
#include <stdio.h>
#define FOO 0xffffffff
#define BAR 0xffffffffu
int
main(void)
{
puts(""
#if FOO - FOO - 1 > 0
"FOO - FOO - 1 > 0\n"
#endif
#if BAR - BAR - 1 > 0
"BAR - BAR - 1 > 0\n"
#endif
);
return 0;
}
It will only print the line with BAR.
The promoted type of UINT_MAX is unsigned int, so it makes sense that
it behaves like uintmax_t (not intmax_t) in preprocessor. I didn't spot
where the standards say this though. In any case, UINT_MAX and
UINT32_MAX have the U suffix in a few other C libraries.
--
Lasse Collin
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public