我经常听到有人说,在编译C和c++程序时,我应该“总是启用编译器警告”。为什么这是必要的?我怎么做呢?

有时我也听到我应该“把警告当作错误”。我应该吗?我怎么做呢?


当前回答

你应该总是启用编译器警告,因为编译器经常会告诉你代码哪里出了问题。为此,您将-Wall -Wextra传递给编译器。

您通常应该将警告视为错误,因为警告通常表示您的代码有问题。然而,通常很容易忽略这些错误。因此,将它们视为错误将导致构建失败,因此您不能忽略这些错误。若要将警告视为错误,请将-Werror传递给编译器。

其他回答

警告包含了一些最熟练的c++开发人员可以放入应用程序中的最佳建议。他们值得留在身边。

C++, being a Turing complete language, has plenty of cases where the compiler must simply trust that you knew what you are doing. However, there are many cases where the compiler can realize that you probably did not intend to write what you wrote. A classic example is printf() codes which don't match the arguments, or std::strings passed to printf (not that that ever happens to me!). In these cases, the code you wrote is not an error. It is a valid C++ expression with a valid interpretation for the compiler to act on. But the compiler has a strong hunch that you simply overlooked something which is easy for a modern compiler to detect. These are warnings. They are things that are obvious to a compiler, using all the strict rules of C++ at its disposal, that you might have overlooked.

关闭或忽略警告,就像选择忽略那些比你更有经验的人的免费建议。这是一个傲慢的教训,当你飞得离太阳太近,翅膀融化了,或者发生记忆损坏错误时,这个教训就结束了。在这两者之间,我愿意随时从天上掉下来!

“将警告视为错误”是这一哲学的极端版本。这里的想法是解决编译器给您的每个警告——您听取每个免费建议并执行它。这对你来说是否是一个好的开发模式取决于你的团队以及你所开发的产品类型。这是僧侣可能有的苦行方式。对一些人来说,效果很好。对另一些人来说,则不然。

在我的许多应用程序中,我们不将警告视为错误。我们这样做是因为这些特定的应用程序需要在多个平台上编译,使用多个不同年代的编译器。有时我们会发现,如果在一个平台上修复一个警告,而不将其转化为另一个平台上的警告,实际上是不可能的。所以我们只是小心行事。我们尊重警告,但我们不会为它们竭尽全力。

一些警告可能意味着代码中可能出现语义错误或可能出现UB。例如;if()之后,一个未使用的变量,一个被局部变量掩盖的全局变量,或者有符号和无符号的比较。许多警告与编译器中的静态代码分析器或在编译时检测到的违反ISO标准有关,这“需要诊断”。虽然在特定情况下,这些事件可能是合法的,但大多数情况下,它们是设计问题的结果。

一些编译器,例如GCC,有一个命令行选项来激活“警告为错误”模式。这是一个很好的工具,如果残酷,教育新手。

将警告视为错误只有一个问题:当你使用来自其他来源的代码时(例如,微软库,开源项目),他们没有正确地完成他们的工作,编译他们的代码会产生大量的警告。

在编写代码时,我总是确保它不会产生任何警告或错误,并在编译之前进行清理,而不会产生任何无关的噪音。我不得不处理的垃圾让我感到震惊,当我不得不构建一个大项目时,看着一串警告从编译器应该只声明它处理了哪些文件的地方经过时,我感到震惊。

我也记录我的代码,因为我知道软件真正的生命周期成本主要来自维护,而不是最初的编写,但这是另一回事……

我曾经在一家制造电子测试设备的大公司(财富50强)工作过。

我的团队的核心产品是一个MFC程序,多年来,它产生了数百个警告。在几乎所有的案例中都被忽略了。

当出现bug时,这简直是一场噩梦。

在那个职位之后,我很幸运地被一家新创业公司聘为第一个开发人员。

我鼓励所有构建都采用“无警告”策略,并将编译器警告级别设置为相当吵闹的级别。

我们的做法是使用#pragma warning - push/disable/pop用于开发人员确定确实没问题的代码,并在调试级别使用日志语句,以防万一。

这种做法对我们很有效。

忽略警告意味着您留下了草率的代码,这不仅会在将来给其他人带来问题,而且还会使您不太注意到重要的编译消息。

编译器输出越多,就越不会有人注意到。越干净越好。这也意味着你知道自己在做什么。警告是非常不专业、粗心和危险的。