小编典典

如何打开(字面上)所有 GCC 的警告?

all

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

  • 你会认为-Wall可能会成功,但不!还是需要-Wextra的。

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

我如何告诉 GCC 启用(没有 if’s、and’s 或 but’s!)它有的 所有 警告?


阅读 94

收藏
2022-06-08

共1个答案

小编典典

你不能。

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

打开 所有内容 将包括-Wdouble-promotion仅与具有 32 位单精度浮点单元的 CPU
相关,该单元在硬件中实现,但在软件中float模拟。doubledouble使用软件仿真一样进行计算并且速度较慢。这与某些嵌入式 CPU
相关,但与硬件支持 64 位浮点的现代台式机 CPU 完全无关。

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

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

Luc Danton 提供了一个很好的例子-Waggregate-return,说明几乎可以肯定对 C++ 代码毫无意义的无用警告。

即你并不真正想要 所有 的警告,你只是认为你想要。

阅读手册,阅读它们,决定您可能想要启用的内容,尝试它们。无论如何,阅读编译器手册是一件好事,走捷径并启用您不理解的警告并不是一个好主意,尤其是在避免使用
RTFM 时。

任何只打开 所有东西 的人都可能这样做是因为他们无能为力,或者是一个尖头的老板说“没有警告”。

有些警告很重要,有些则不重要。你必须有区别,否则你会搞砸你的程序。例如,考虑-Wdouble- promotion。如果您正在使用嵌入式系统,您可能需要这个;如果你在桌面系统上工作,你可能不会。你想要-Wtraditional吗?我对此表示怀疑。

编辑: 另请参阅-Wall-all
以启用所有
作为 WONTFIX 关闭的警告。

编辑 2: 为了回应 DevSolar 关于 makefile 需要根据编译器版本使用不同警告的抱怨,如果-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))
2022-06-08