当前位置: 首页 > 知识库问答 >
问题:

我如何打开GCC的所有警告?

杜浩壤
2023-03-14

我想启用 - 从字面上看 - GCC的所有警告。(你会认为这很容易...

> < li>

您可能会认为-Wall可能会成功,但事实并非如此!你仍然需要-Wextra。

你会认为-Wextra可能会成功,但没有!并非此处列出的所有警告(例如-Wshadow)都由此启用。我仍然不知道这个列表是否全面。

我如何告诉GCC启用(没有if,and,or but!)它拥有的所有警告?

共有3个答案

谷梁迪
2023-03-14

在启用所有警告的情况下进行编程是不可能的(除非你要忽略它们,但是,为什么要打扰呢?例如,假设您使用以下标志集:-创建原型-传统

即使启用了两个警告,以下程序也会抱怨。

/tmp $ cat main.c 
int main(int argc, char **argv) {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c: In function ‘main’:
main.c:1:5: warning: traditional C rejects ISO C style function definitions [-Wtraditional]
 int main(int argc, char **argv) {
     ^

你可能会想“好吧,那我就用老式的原型”。不,这行不通。

/tmp $ cat main.c 
int main(argc, argv)
    int argc;
    char **argv;
{
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main(argc, argv)
     ^

不,不指定任何原型也是错误的,因为编译器也会抱怨。

/tmp $ cat main.c 
int main() {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main() {
     ^

如果您在程序中定义任何函数,则不能使用所有标志,因为编译器会抱怨任何可以想象的函数定义。

对于C语言,这是可能的(-Wtraditional标志不存在),并且可以编译非常简单的程序。要启用所有警告,请使用以下警告列表(可能有些警告是重复的,因为我没有费心过滤-Wall启用的警告)。

-Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo -Wextra -Wall -Waddress -Waggregate-return -Warray-bounds -Wno-attributes -Wno-builtin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Winline -Wno-int-to-pointer-cast -Wno-invalid-offsetof -Winvalid-pch -Wunsafe-loop-optimizations -Wlogical-op -Wlong-long -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wno-mudflap -Wno-multichar -Wnonnull -Wno-overflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-aliasing=1 -Wstrict-overflow=5 -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas -Wno-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings
许明朗
2023-03-14

我同意前面的回答,即启用所有警告可能并不有益,但GCC确实提供了一种合理方便的方法来实现这一点。命令

gcc -Q --help=warning

提供了所有受支持的警告选项的列表,其中包含有关这些选项是否处于活动状态的信息。这可以用来找出哪些选项(未启用),例如-Wall-Wextra

gcc -Wall -Wextra -Q --help=warning

要启用所有警告,可以使用一些正则表达式来提取命令行参数

gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n'

对于我当前的GCC,这给出了:

-Wabi-Wabi-tag-Waddress-wagregate-return-Waggressive-loop-optimizations-Wali asing-wa ign-commons-Wampersand-Warray-bounds-Warray-temporaries-was sign-intercept-wat tributes-Wbad-function-cast-Wbool-compare-Wbuiltin-macro-redefined-Wc-compat-Wc 14-compat-Wc-binding-type-Wc90-c99-compat-Wc99-c11-compat-wcu -Winvalid-offset of-Winvalid-PCH-w jump-misses-init-Wline-truncation-wl iteral-suffix-Wlogical-not-括号-Wlogical-op-Wlong-long-Wmain-Wmaybe-未初始化-wme mset-transposed-args-wmi ssing-大括号-wmi ssing-declarations-wmi ssing-field-initializer-wmi ssing-include-dirs-wmi ssing-parameter-type-wmi ssing-prototypes-wmultic char-Wnarrowing-Wnested-externs-wni -w system-headers-w target-lifetime-w traditional-w traditional-conversion-Wtrampolines-Wtrigraphs-Wtype-limits-wundered-selector-Wundef-Wunderflow-wun initialized-Wunknown-pragmas-Wunsafe-loop-optimizations-Wunsuffixed-float-constants-Wunused-Wunused-but-set-parameter-Wunused-set-variable-Wunused-dummy-argument-Wunused-function-wunus

这现在可以用来调用海湾合作委员会,即

gcc $(gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n')

但是请注意,这将导致警告,因为某些警告选项仅适用于某些语言(例如< code>C )。可以通过使用更多的正则表达式来只包含当前语言允许的选项,或者在调用结束时添加一个适当的< code>-Wno-whatever来避免这些问题。

鱼意远
2023-03-14

你不能。

GCC 4.4.0的手册仅针对该版本进行了全面介绍,但它确实列出了4.4.0的所有可能警告。不过,它们并不都在您链接到的页面上。例如,一些特定于语言的选项在C选项或Objective-C选项的页面上。要找到它们,您最好查看选项摘要

打开一切将包括< code>-Wdouble-promotion,它仅与具有32位单精度浮点单元的CPU相关,该单元在硬件中实现< code>float,但在软件中模拟< code>double。以< code>double的形式进行计算将使用软件仿真,速度较慢。这与一些嵌入式CPU相关,但与硬件支持64位浮点的现代桌面CPU完全无关。

另一个通常不太有用的警告是-W传统,它警告在传统C中具有不同含义(或不起作用)的格式完美的代码,例如"string""concatenathtml" target="_blank">ion"或ISO C函数定义!你真的关心与30年前的编译器的兼容性吗?你真的想要编写int inc(int i){返回i 1;}的警告吗?

我认为-Weffc太吵了,没有用。它基于过时的有效C第一版,并警告完全有效的C结构(并且在本书的后续版本中指南发生了变化)。我不想被警告我没有在构造函数中初始化一个std::字符串成员;它有一个默认构造函数,完全按照我的要求做。我为什么要编写m_str()来调用它?有用的-Weffc警告对编译器来说很难准确检测(给出误报),而不有用的警告,例如显式初始化所有成员,只会产生太多噪声,给出误报。

Luc Danton提供了一个很好的示例,说明来自-Wcomper-back的无用警告,几乎可以肯定它对C代码没有意义。

也就是说,你并不真的想要所有的警告;你只是认为你知道。

浏览手册,阅读它们,决定您可能想要启用哪些,并尝试它们。无论如何,阅读编译器手册是一件好事,走捷径并启用您不理解的警告不是一个好主意,尤其是如果它是为了避免必须使用RTFM。

任何一个打开所有东西的人可能要么是因为他们一无所知,要么是因为一个尖头头发的老板说“没有警告”

有些警告很重要,有些则不然。你必须有鉴别力,否则你会搞砸你的程序。例如,考虑-两倍促销。如果您正在开发嵌入式系统,则可能需要这个;如果您使用的是桌面系统,则可能不会。你想要 -传统吗?我怀疑。

另请参见-Wall all以启用所有关闭为WONTFIX的警告。

针对DevSolar抱怨makefiles需要根据编译器版本使用不同的警告,如果< code>-Wall -Wextra不合适,那么使用特定于编译器和特定于版本的CFLAGS并不困难:

compiler_name := $(notdir $(CC))
ifeq ($(compiler_name),gcc)
compiler_version := $(basename $(shell $(CC) -dumpversion))
endif
ifeq ($(compile_name),clang)
compiler_version := $(shell $(CC) --version | awk 'NR==1{print $$3}')
endif
# ...
wflags.gcc.base := -Wall -Wextra
wflags.gcc.4.7 := -Wzero-as-null-pointer-constant
wflags.gcc.4.8 := $(wflags.gcc.4.7)
wflags.clang.base := -Wall -Wextra
wflags.clang.3.2 := -Weverything
CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))
 类似资料:
  • 我正在使用minGW的minw-w64(x64)分叉nuwen.net.这是来自gcc的7.1版本: 我正在编译这个程序: 带有警告和c11标准: 我得到了这些警告: 我想在没有警告的情况下打印size_t,但在这种情况下不知道正确的格式说明符。

  • 问题内容: 由于弹出窗口 ,Selenium投掷出现问题 警报具有和按钮。我知道两种解决方法 第一种方法是重新打开一个新会话 第二种方法是使用Robot类 但是,这种方法不是省时的。有什么更好的办法吗? 问题答案: 这应该可以解决问题:

  • 技巧 你的程序编译通过了,但并不意味着已经万事大吉,也许还存在一些不规范的地方,或者一些错误隐患。建议,使用-Wall选项打开所有的警告信息,把所有的警告都处理掉。 $ gcc -Wall ... 详情参见 gcc手册

  • 当我试图在Xamarin/Android应用程序中写入文本文件时,我会间歇性地遇到太多打开文件异常。我明白这是因为每个Android应用程序都有打开文件的数量限制,很明显,我的应用程序在某些情况下超过了它。因此,我必须留下一些文件打开/没有妥善处理。我想知道我是否可以通过编程列出我的应用程序在任何给定时间打开的文件?显然,操作系统知道这一点,有可能在我的应用程序中做到这一点吗?这将帮助我发现问题。

  • 我正在docker容器中部署一个应用程序,它在启动时随机分配端口。问题是我想使用< code>docker-compose,但是有没有一种方法可以使用docker-compose公开服务的所有端口?如果没有docker-compose,我会使用< code>docker run...-P 谢谢

  • 我想用一些js保护我的本地静态html网站的密码,这样当我在pc中打开我的本地html文件时,它会附带一个表单来填写我的用户id和我自己的密码,我已经保存了密码,当我点击enter键时,应该会打开我的索引。仅当密码正确时才使用html文件。目前我的代码是