C的推荐gcc警告选项[关闭]


Answers:


48

我通常使用:

    gcc -m64 -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual \
        -Wstrict-prototypes -Wmissing-prototypes

对于那些不使用它的人(我的代码第一次被这些标志编译的人)来说,这个集合吸引了很多人;它很少给我带来问题(尽管-Wcast-qual有时会很麻烦)。


1
这些天来,我发现我必须添加' -Wdeclaration-after-statement,以检测MSVC(基本上仍然是C89编译器)无法处理的代码。讨厌。添加“ -Wextra”也可以发现其他一些问题。
乔纳森·莱夫勒

2
另外,添加一个-O3或类似的东西也是一个好主意。仅在优化代码时才会生成警告。
乔纳森·勒夫勒

3
根据gcc doc,-O2是发现警告的最佳方法。我不确定-O3是否暗示-O2还是允许生成更多警告。
Offirmo 2012年

3
如果您不在64位环境中,请跳过-m64。
2013年

1
同时使用-m32 和和 -m64(当然,在单独的运行中)可以更好地保护您免受使用printf()scaf()转换规范方面的各种错误的影响。
乔纳森·勒夫勒

40

截至2011-09-01,使用gcc版本4.6.1

我当前的“开发”别名

gcc -std = c89 -pedantic -Wall \
    -无遗漏括号-Wextra-无遗漏字段初始化器-Wformat = 2 \
    -Wswitch-default -Wswitch枚举-Wcast-align -Wpointer-arith \
    -Wbad-function-cast -Wstrict-overflow = 5 -Wstrict-原型-Winline \
    -Wundef -Wnested-externs -Wcast-qual -Wshadow -Wunreachable-code \
    -Wologic-op -Wfloat-equal -Wstrict-aliasing = 2 -Wredundant-decls \
    -Wold样式的定义-Werror \
    -ggdb3 \
    -O0 \
    -fno-省略帧指针-ffloat-store -fno-common -fstrict-aliasing \
    -lm

“发布”别名

gcc -std = c89 -pedantic -O3 -DNDEBUG -flto -lm

截至2009-11-03

“开发”别名

gcc -Wall -Wextra -Wformat = 2 -Wswitch-default -Wcast-align -Wpointer-arith \
    -Wbad函数转换-Wstrict原型-Winline -Wundef -Wnested-externs \
    -Wcast-qual -Wshadow -Wwrite-strings -Wconversion -Wunreachable-code \
    -Wstrict-aliasing = 2 -ffloat-store -fno-common -fstrict-aliasing \
    -lm -std = c89 -pedantic -O0 -ggdb3 -pg --coverage

“发布”别名

gcc -lm -std = c89 -pedantic -O3 -DNDEBUG --combine -fwhole-program -funroll-loops

1
-Wfloat-equal添加到我的别名。谢谢你马克
PMG

4
请注意,至少在最新版本的gcc中,-Wstrict-aliasing=2实际上降低了所-Wstrict-aliasing=3暗示的警告级别-Wall
nwellnhof,2015年

15

我喜欢-Werror。保持代码自由警告。


21
没有-Werror,所有其他警告选项将毫无意义。将警告视为错误几乎是确保警告得到解决的唯一方法。如果他们只是警告,开发人员可能会决定留下一个,因为他确定这是无效的。甚至可能是事实,但是下一位开发人员将不会修复他所引入的警告,因为他没有在所有其他开发人员之间看到它,或者只是一个警告。
克里斯托弗·普罗斯特

6
我不同意Kristof,因为很多时候,我宁愿先编译工作副本,然后解决错误。
Yktula 2010年

9
我理解为什么这样做很诱人,但是当/如果您有一份有效的副本,您将更有可能将其原样保留,因为“有效”。在企业环境中,这种风险甚至更高,在这种环境中,您必须说服老板留出一些时间来修正警告。
JesperE

2
我考虑摆脱使用#warning的良好副作用-Werror
JesperE

3
如果您使用开放源代码的东西-Werror,则默认情况下不会在您的版本中使用它,这会使使用您不同编译器版本的打包程序感到烦恼,因为警告会随编译器版本的变化而变化,有时对您免费发出警告的代码会向其他人发出警告,并且然后他们必须深入研究您的构建系统以将其关闭。
Spudd86

15

我从C ++开始,所以当我切换到学习CI时,请确保要肛门外:

-fmessage-length = 0
-ansi -pedantic -std = c99
-恐怖
-壁
-Wextra
-Wwrite-strings
-Winit-self
-Wcast-align
-Wcast质量
-Wpointer-arith
-锯齿锯齿
-Wformat = 2
-遗失声明
-Wmissing-include-dirs
-未使用的参数
-未初始化
-老式的定义
-严格的原型
-遗忘原型

5
您可以同时使用-ansi -pedantic -std = c99吗?-ansi是否与c89大致相同?如果可以的话,如何使用c99标志?
约翰

2
@Johan-可以,实际上没有必要,正如我最近发现的那样。-ansi表示-std = <default>,因此实际上您可以说-std = c99 -pedantic并获得完全相同的效果。我确实倾向于使用它,只是为了文档效果。我觉得它的内容是:“此代码是使用标准C99的ANSI标准(太好了!)。” 紧接着通常是-Wno-long-long或类似的... ANSI标准的任何例外。
汤姆,

9

获取您所使用的GCC版本的手册,找到所有警告可供选择,然后关闭只有那些您有一个令人信服的理由这样做。(例如,不可修改的第三方标头会给您很多警告。)记录这些原因。(在Makefile或您设置这些选项的任何位置。)请定期检查设置,并在每次升级编译器时进行检查。

编译器是您的朋友。警告是您的朋友。给编译器尽可能多的机会告诉您潜在的问题。


1
仅供参考,手册未提供警告的完整列表。但是,您可以在此处找到此类列表以及用于生成它们的工具。
凯尔·斯特兰德

5

我还使用:

-Wstrict-overflow = 5

如果我编写依赖于整数的溢出行为的代码,则可能会捕获那些讨厌的错误。

和:

-Wextra

这也使一些不错的选择成为可能。虽然大多数是用于C ++。


4
-Wextra似乎是-W的新名称(仍受支持)
Sard


2

-pedantic -Wall -Wextra -Wno写字符串-Wno未使用参数

对于“伤害我很多”模式,我不使用-Wno ...

我喜欢免费提供我的代码警告,尤其是对于C ++。尽管通常可以忽略C编译器警告,但是许多C ++警告显示了源代码中的基本缺陷。


3
因为工具链可以自由地将字符串文字放入只读存储器中。
DevSolar

3
为什么-不使用参数?它很少会指出实际的问题(禁用它的确切危险是:“很少”:最不可能检测到的错误)。例如,如果可能触发Foo(int dndu, int dndv) : dndu_(dndu), dndv_(dndu) {}->相对难以发现。如果您因该警告而烦恼,则只需删除参数foo (int /*q*/),这也可以提高代码的可读性。
塞巴斯蒂安·马赫,

在重构过程中,有时我会误用局部
变量遮盖

1

-学徒错误


2
@unexist尝试安装clang(LLVM项目的C编译器),然后使用进行编译,-Weverything您将看到编译真正变得多么有趣(某些警告完全是疯狂的,但从技术上讲它们是正确的)。
Mecki


1

-Wredundant-Decls -Wnested-externs -Wstrict-prototypes -Wextra -Werror隐式函数声明-Wunused -Wno-unused-value -Wreturn-type


1

现在我使用:

-Wall -W -Wextra -Wconversion -Wshadow -Wcast-qual -Wwrite-strings -Werror

我主要从《 gcc入门》一书中获得该列表,然后从Ulrich Drepper关于防御性编程的推荐书中获得该列表(http://people.redhat.com/drepper/Defensive-slides.pdf)。

但是我的名单上没有任何科学依据,感觉就像是一份不错的清单。

/约翰


注意:我不喜欢那些书呆子的标志。

注意:我认为-W和-Wextra差不多是同一件事。


2
使用-Wconversion之后,花了几个小时测试我的代码中的各种数据类型并重新构建,因此我研究了-Wconversion,一般不建议使用它。问题在于它会生成有关代码的警告,例如:char a = 5; char b = a-1; 这使用的是gcc 4.3.2(Debian 4.3.2.-1.1)
James Morris

1
-Wconversion警告可以通过以下方式消除(例如,在上面的注释中):char a = 5; char b =(字符)(a-1); 注意括号。
詹姆斯·莫里斯

1

我一般只是用

gcc -Wall -W -Wunused-parameter -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wsign-compare -Wconversion -Wshadow -Wcast-align -Wparentheses -Wsequence-point -Wdeclaration-after-statement -Wundef -Wpointer-arith -Wnested-externs -Wredundant-decls -Werror -Wdisabled-optimization -pedantic -funit-at-a-time -o

1

除非您指定-O,否则有关未初始化变量的警告将不起作用,因此我将其包含在列表中:

-g -O -Wall -Werror -Wextra -pedantic -std=c99

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.