- 将
-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函数),并且函数声明具有完整的原型——没有空括号()——和使用 -Wall 和 -Wextra 发现许多其他常规问题,包括格式字符串和 printf() 和 scanf() 系列函数的参数之间的不匹配。