如何禁用GNU C扩展?

时间:2016-08-14 07:10:57

标签: 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标志来&#34;禁用&#34;不必要的扩展,但我没有得到任何错误。

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

我在哪里弄错了?

1 个答案:

答案 0 :(得分:11)

  • -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
$
  

那么-std=c99是什么意思?

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

  

-Wpedantic
  -pedantic

     

发出严格的ISO C和ISO C ++要求的所有警告;拒绝所有使用禁止扩展的程序,以及其他一些不遵循ISO C和ISO C ++的程序。对于ISO C,遵循由所使用的任何-std选项指定的ISO C标准的版本。

     

有效的ISO C和ISO C ++程序应该在有或没有此选项的情况下正确编译(尽管少数几个需要-ansi-std选项指定所需的ISO C版本)。但是,如果没有此选项,则还支持某些GNU扩展和传统的C和C ++功能。使用此选项,它们将被拒绝。

     

-Wpedantic不会导致使用名称以__开头和结尾的备用关键字的警告消息。在__extension__之后的表达式中也禁用了警示警告。但是,只有系统头文件才能使用这些转义路由;应用程序应该避免它们。请参阅备用关键字。

     

有些用户尝试使用-Wpedantic检查程序是否符合严格的ISO C标准。他们很快发现它没有做到他们想要的东西:它找到了一些非ISO实践,但不是全部 - 只有ISO C需要诊断的那些,还有一些其他已经添加了诊断的。

     

报告任何不符合ISO C的功能在某些情况下可能会有用,但需要大量的额外工作,并且与-Wpedantic完全不同。我们没有计划在不久的将来支持这样的功能。

     

如果用-std指定的标准表示C的GNU扩展方言,例如'gnu90'或'gnu99',则存在相应的基本标准,即GNU扩展方言所基于的ISO C的版本。来自-Wpedantic的警告在基准标准要求的地方给出。 (仅对不在指定的GNU C方言中的功能给出这样的警告是没有意义的,因为根据定义,C的GNU方言包括编译器支持给定选项的所有功能,并且没有什么可以警告的。)

还有一个不同的选项会产生迂腐错误:

  

-pedantic-errors

     

每当基本标准(请参阅-Wpedantic)需要诊断时发出错误,在某些情况下,在编译时存在未定义的行为,在某些情况下不会阻止编译有效的程序符合标准。这不等同于-Werror=pedantic,因为此选项启用了错误,后者未启用,反之亦然。

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

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