c - 如何禁用 GNU C 扩展?

标签 c gcc

正如您在下面的代码中看到的,我在 main() 中引入了一个嵌套函数:

#include <stdio.h>

int main(){
 int a=5;
 printf("%d\n",a);
 {
  int a=10;
  printf("%d\n",a);
 }
 printf("%d\n",a);

 //Nested function
 int main(int a){
 if(a>0)printf("%d\n",a--);
 return 0;
 }

 main(7);
 return 0;
}

据我所知,我在 gcc 中使用了 -std=c99 标志来“禁用”不必要的扩展,但我没有收到任何错误。

gcc temp3.c -std=c99 -o temp3.out

我哪里做错了?

最佳答案

  • -pedantic-Werror 添加到命令行。

在 Mac OS X 10.11.6 上使用 GCC 6.1.0,在文件 ped73.c 中使用您的原始代码和我的默认编译选项,我得到:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition ped73.c -o ped73 
ped73.c:3:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 int main(){
     ^~~~
ped73.c: In function ‘main’:
ped73.c:3:5: error: old-style function definition [-Werror=old-style-definition]
ped73.c:13:6: error: ‘main’ takes only zero or two arguments [-Werror=main]
  int main(int a){
      ^~~~
ped73.c:13:6: error: ‘main’ is normally a non-static function [-Werror=main]
$

将嵌套函数重命名为 nested 并使用 int main(void),我得到:

$ gcc -O3 -g-std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes 
>     -Wold-style-definition -o ped73
$

使用额外选项 -pedantic 我得到:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -pedantic ped73.c -o ped73 
ped73.c: In function ‘main’:
ped73.c:13:2: error: ISO C forbids nested functions [-Werror=pedantic]
  int nested(int a){
  ^~~
cc1: all warnings being treated as errors
$

Then what's the point of -std=c99?

-std=c99 标志禁用 GCC 认为应该禁用的 GNU 扩展——例如 POSIX 版本等。参见 C Dialect Options -std=的含义;见Warning Options -pedantic的含义。

-Wpedantic
-pedantic

Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.

Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the required version of ISO C). However, without this option, certain GNU extensions and traditional C and C++ features are supported as well. With this option, they are rejected.

-Wpedantic does not cause warning messages for use of the alternate keywords whose names begin and end with __. Pedantic warnings are also disabled in the expression that follows __extension__. However, only system header files should use these escape routes; application programs should avoid them. See Alternate Keywords.

Some users try to use -Wpedantic to check programs for strict ISO C conformance. They soon find that it does not do quite what they want: it finds some non-ISO practices, but not all—only those for which ISO C requires a diagnostic, and some others for which diagnostics have been added.

A feature to report any failure to conform to ISO C might be useful in some instances, but would require considerable additional work and would be quite different from -Wpedantic. We don't have plans to support such a feature in the near future.

Where the standard specified with -std represents a GNU extended dialect of C, such as ‘gnu90’ or ‘gnu99’, there is a corresponding base standard, the version of ISO C on which the GNU extended dialect is based. Warnings from -Wpedantic are given where they are required by the base standard. (It does not make sense for such warnings to be given only for features not in the specified GNU C dialect, since by definition the GNU dialects of C include all features the compiler supports with the given option, and there would be nothing to warn about.)

还有一个不同的选项会给出迂腐的错误:

-pedantic-errors

Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard. This is not equivalent to -Werror=pedantic, since there are errors enabled by this option and not enabled by the latter and vice versa.


关于使用哪些 GCC 编译器选项存在多个问题,包括:

毫无疑问,还有许多其他的可以添加到该列表中。基本上,我使用的默认选项确保函数在使用前声明(或者,在使用前定义为 static 函数),并且函数声明具有完整的原型(prototype)——没有空括号() — 并使用 -Wall-Wextra 来发现许多其他常规问题,包括格式字符串和参数之间的不匹配printf()scanf() 函数族。

关于c - 如何禁用 GNU C 扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38939991/

相关文章:

gcc - 未通过带有 __attribute__((fastcall)) 的寄存器获取从 asm 传递到 C 的函数参数

c - 扫描仪不工作(C 代码)

c - 指针队列提取在C中进入无限循环

从 16 位架构中的给定索引计算位掩码

c++ - 64位系统上的NULL定义问题

gcc - AOSP中HIDL的接口(interface)头文件在哪里?

c - 如何在 C 中强制使用返回值

c - ANTLR3 C 目标 - 解析器返回 'misses' 根元素

c++ - 内联汇编; float 的位运算;这里出了什么问题?

c++ - 段错误的发生取决于gcc编译命令中的cpp序列?