- 在命令行中添加
-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 版本等。请参见 C 语言方言选项 以了解 -std=
的含义;请参见 警告选项 以了解 -pedantic
的含义。
-Wpedantic
-pedantic
发出严格的ISO C和ISO C++所要求的所有警告,拒绝使用禁止扩展以及一些不符合ISO C和ISO C++规范的程序。对于ISO C,遵循任何使用-std
选项指定的ISO C标准版本。
有效的ISO C和ISO C++程序应该可以在有或没有此选项的情况下正确编译(尽管极少数需要-ansi
或指定所需ISO C版本的-std
选项)。但是,如果没有此选项,则还支持某些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
函数),并且函数声明具有完整的原型 - 没有空括号()
- 并使用-Wall
和-Wextra
来检测许多其他常见问题,包括printf()
和scanf()
函数族中格式字符串和参数之间的不匹配。
-pedantic -Werror
应该可以解决这个问题。 - Jonathan Leffler-std=c99
标志禁用了 GCC 认为应该被禁用的 GNU 扩展,例如 POSIX 版本等。请参阅 C 语言方言选项 以了解-std=
的含义;请参阅 警告选项 以了解-pedantic
的含义。 - Jonathan Leffler