严格C89模式下使用uint64_t为何无编译器警告?
C89模式下int64_t与long long的编译警告差异问题
我正在编写严格符合ISO C89标准的代码,long long并非C89标准内容,在C99之前通常作为编译器扩展实现,正常使用时编译器应该发出警告。但在32位编译(-m32)模式下,当int64_t被展开为long long时,gcc和clang都没有发出警告。
示例代码
/* 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; }
编译命令
clang-17 -m32 -std=c89 -Wall -Wextra -Werror -pedantic -pedantic-errors test.c # 或 x86_64-pc-linux-gnu-gcc-13.2.1 -m32 -std=c89 -Wall -Wextra -Werror -pedantic -pedantic-errors test.c
编译时无任何警告或错误,但预处理结果显示int64_t实际上是long long int的typedef。可如果把代码中的int64_t替换为long long或__INT64_TYPE__,编译器就会报错。为什么long long和int64_t的行为会有这种差异?
原因解析
核心原因是编译器对系统头文件和用户代码采用了不同的标准合规检查策略:
<stdint.h>属于系统头文件,编译器默认会放宽对系统头文件的严格检查,允许其中使用一些不符合当前指定标准的扩展语法(比如C89下的long long),以此保证系统库的兼容性。- 用户自己编写的代码则会被严格按照指定的
-std=c89标准检查,所以直接使用long long或__INT64_TYPE__会触发警告或错误。
额外检查方法
如果需要让编译器也检查系统头文件的C标准合规性,可以通过以下步骤操作(针对clang):
- 使用
clang -v <原编译参数>...命令,生成clang实际执行的完整编译命令 - 将命令中所有的
-internal-isystem替换为-I - 执行修改后的命令,clang就会输出系统头文件不符合C89标准的错误信息
内容的提问来源于stack exchange,提问作者R-R
相关产品推荐
相关产品推荐

