我试图找到测试 strict C90 一致性时要使用的 gcc 标志的组合是什么。根据上一篇文章:GCC options for strictest C code?,我应该只需要一个 --std=c90。
但是这是我尝试过的:
$ cat t.c
#include <stdint.h> /* added in C99 */
int main()
{
uint64_t t;
return 0;
}
$ gcc -std=c90 -ansi -pedantic t.c
上面的方法运行良好(没有产生警告/错误)。
有谁知道:
编辑:
抱歉我的措辞,是的,我真的很想模仿严格符合 C90 的编译器,换句话说,如果代码尝试使用稍后添加的任何功能(想到 C99),它应该会失败。因此,
pthread
包含标头ought,以便在以GNU/GCC称为C90模式编译时发出警告(就像stdint.h标头应该在没有C99的情况下产生警告一样)。 -学究式很好地警告我有关 long long
的使用,我不明白为什么它不应该警告我关于 uint64_t
。
我使用了 ISO/IEC 9899:1990 的术语,引用自:
1990 年,ANSI C 标准(经过格式更改)被 国际标准化组织 (ISO) 简称为 ISO/IEC 9899:1990,有时称为 C90。因此,术语“C89” 和“C90”指的是相同的编程语言。
编辑2:
GCC 文档其实很清楚:
作为 C99 标准一部分的某些功能被接受为 C90 模式下的扩展,以及 C11 的一些功能 标准被接受为 C90 和 C99 模式的扩展。
所以我的问题改写为:
C90 合规性并不意味着编译器不能提供 C90 标准中未提及的 other 标头。 (例如,
sys/socket.h
。)如果您出于某种奇怪的原因想要禁止这些,您可以传递 -I
选项来添加额外的包含路径,并在该路径中放置所有仅 C99 标头的版本简直就是#error Don't include me
。
请记住,GCC 本身是指定 C 标准的“独立”实现;这样的实现仅提供标准头文件的一小部分,并且几乎不提供 C 标准库的实际功能,而是依赖另一方(例如 Linux 系统上的glibc
)来提供 C 标准库的功能。
您所寻求的不仅是在您使用 C90 中没有的 C99/C11/GNU language
功能时发出警告,而且是在您使用 C90 本身未定义的 library 函数时发出警告。遗憾的是,由于上述原因,编译器无法单独做到这一点——它与它所使用的libc
无关。在
glibc
系统上,C 标准库将采用由 -std=c90
或 -ansi
定义的宏:使用
__STRICT_ANSI__
选项时,宏
是预定义的。某些头文件可能会注意到此宏,并避免声明 ISO 标准不要求的某些函数或定义某些宏;这是为了避免干扰任何可能将这些名称用于其他用途的程序。 并通过关闭免费扩展为您提供一些帮助:
-ansi
如果您使用
‘gcc -ansi’
编译程序,则只能获得 ISO C 库功能,除非您通过定义一个或多个功能宏明确请求其他功能。
但是,这仅涵盖扩展和 POSIX 而非 ISO C 函数;如果 ISO C 和 POSIX.1 中对函数的行为指定不同,它也救不了你!
//file t.c
union foo { int i; double d; };
union foo f = { .d = 4 }; // designated initializers introduced in c99
int main() { return 0;}
编译时
$gcc -pedantic -std=c90 t.c
t.c:3:17: warning: ISO C90 forbids specifying subobject to initialize [-Wpedantic]
3 | union foo f = { .d = 4 };