严格 C90 代码的 GCC 选项?

问题描述 投票:0回答:3

我试图找到测试 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

上面的方法运行良好(没有产生警告/错误)。

有谁知道:

  1. gcc 标志严格遵守 ISO/IEC 9899:1990
  2. 具有不同标志集的不同编译器(tcc、clang...)?

编辑:

抱歉我的措辞,是的,我真的很想模仿严格符合 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 模式的扩展。

所以我的问题改写为:

  • linux系统上有没有严格符合C90的编译器+标准include头?
c gcc iso c89
3个回答
14
投票

C90 合规性并不意味着编译器不能提供 C90 标准中未提及的 other 标头。 (例如,

sys/socket.h
。)如果您出于某种奇怪的原因想要禁止这些,您可以传递
-I
选项来添加额外的包含路径,并在该路径中放置所有仅 C99 标头的版本简直就是
#error Don't include me


2
投票

请记住,GCC 本身是指定 C 标准的“独立”实现;这样的实现仅提供标准头文件的一小部分,并且几乎不提供 C 标准库的实际功能,而是依赖另一方(例如 Linux 系统上的glibc)来提供 C 标准库的功能。


您所寻求的不仅是在您使用 C90 中没有的 C99/C11/GNU

language

功能时发出警告,而且是在您使用 C90 本身未定义的 library 函数时发出警告。遗憾的是,由于上述原因,编译器无法单独做到这一点——它与它所使用的libc无关。在

glibc
系统上,C 标准库将采用由
-std=c90
-ansi
定义的宏:

使用
__STRICT_ANSI__

选项时,宏

-ansi
是预定义的。某些头文件可能会注意到此宏,并避免声明 ISO 标准不要求的某些函数或定义某些宏;这是为了避免干扰任何可能将这些名称用于其他用途的程序。


并通过关闭免费扩展为您提供一些帮助:

如果您使用
‘gcc -ansi’

编译程序,则只能获得 ISO C 库功能,除非您通过定义一个或多个功能宏明确请求其他功能。



但是,这仅涵盖扩展和 POSIX 而非 ISO C 函数;如果 ISO C 和 POSIX.1 中对函数的行为指定不同,它也救不了你!


0
投票

//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 };

© www.soinside.com 2019 - 2024. All rights reserved.