I’m trying to write strict ISO C89-compliant code. Since long long
is not standard and is often implemented as compiler extensions before C99, the compiler should warn me it when I use it. However, when using either gcc or clang, there’s no warning when int64_t
is used and expands to long long
(with 32-bit compilation -m32
). Is there any way to make the compiler warn me?
For example:
/* test.c */
#include <stdint.h>
#include <stdio.h>
int main(void) {
printf("The size of an int64_t is %u.n", (unsigned)sizeof(int64_t));
return 0;
}
Compiled with clang or gcc:
clang-17 -m32 -std=c89 -Wall -Wextra -Werror -pedantic -pedantic-errors test.c
# or
x86_64-pc-linux-gnu-gcc-13.2.1 -m32 -std=c89 -Wall -Wextra -Werror -pedantic -pedantic-errors test.c
They issue no warning or error, even if the int64_t
is actually a typedef to long long int
, since clang-17 -m32 -std=c89 -E -dD -Wall -Wextra -Werror -pedantic -pedantic-errors test.c
gives me:
...
#define __INT64_TYPE__ long long int
#define __INT64_FMTd__ "lld"
#define __INT64_FMTi__ "lli"
#define __INT64_C_SUFFIX__ LL
...
and in /path/to/clang/17/include/stdint.h
there’s
...
#ifdef __INT64_TYPE__
# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
typedef __INT64_TYPE__ int64_t;
# endif /* __int8_t_defined */
typedef __UINT64_TYPE__ uint64_t;
# undef __int_least64_t
...
But if I replace int64_t
with long long
or __INT64_TYPE__
in the above test.c
the compiler will complain about it. So why there’s a behavioral difference between long long
and uint64_t
?
The most relevant question on SO seems to be this: “/questions/62937049” and this: “/questions/26502307”, but their answers don’t seem to explain why there’s no warning when using -m32
. (In -m64
mode uint64_t
is not a problem since it expands to long
, which is in C89 standard).