2016-08-14 93 views
3

正如你可以在下面的代码中看到的,我介绍了一个嵌套函数内main()如何禁用GNU C扩展?

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

至于我能理解我用-std=c99标志GCC为“禁用”的不必要的扩展,但我没有得到任何错误。

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

哪里有我犯的错?

+4

添加'-pedantic -Werror'应该可以解决这个问题。 –

+0

那么-std = c99标志有什么用? –

+0

'-std = c99'标志禁用GCC认为应该禁用的GNU扩展 - 例如POSIX版本等。请参阅[C语言选项](https://gcc.gnu.org/onlinedocs/gcc/C- Dialect-Options.html#C-Dialect-Options)来表示'-std ='的含义;有关'-pedantic'的含义,请参阅[警告选项](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options)。 –

回答

7
  • -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。通过严格的ISO C和ISO C++要求

-Wpedantic
-pedantic

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

有效的ISO C和ISO C++程序应该在有或没有此选项的情况下正确编译(尽管极少数需要-ansi-std选项指定所需版本的ISO C)。但是,如果没有这个选项,也支持某些GNU扩展和传统的C和C++特性。有了这个选项,他们被拒绝。

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

一些用户尝试使用-Wantantic来检查程序是否符合严格的ISO C标准。他们很快就发现它并没有达到他们想要的水平:它找到了一些非ISO的做法,但不是所有的只有ISO C需要诊断的那些做法,以及其他一些诊断已经添加了的做法。

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

如果-std指定的标准表示C的GNU扩展方言,如'gnu90'或'gnu99',则存在相应的基本标准,GNU扩展方言所依据的ISO C版本。 -Wpedantic给出的警告在基本标准要求的地方给出。 (这种警告只适用于不在指定的GNU C方言中的功能是没有意义的,因为根据定义,C的GNU方言包括编译器支持的所有功能,并且没有任何可警告的内容。)


有多种问题,哪些GCC编译器选项使用,包括:

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

+0

这是我在将'-pedantic'添加到我的默认编译字符串时偶然发现的。我发现它的唯一记录是[** GCC **支持的语言标准](https://gcc.gnu.org/onlinedocs/gcc/Standards.html) –

+0

可能要强调并解释您对' - 墙-Wextra'。这些会导致编译器报告其默认情况下未配置的各种问题。并非所有这些都与避免gcc扩展有关,但它们担心会指出错误(可疑转换等),或者不能像其他编译器那样按预期工作。如果'-Werror'不会导致警告终止,则会采取“不接受触发警告的代码”的故意策略。 – Peter