我经常听到在编译 C 和 C++ 程序时我应该“始终启用编译器警告”。为什么这是必要的?我怎么做?
有时我也听说我应该“将警告视为错误”。我是不是该?我怎么做?
原文由 n. m. 发布,翻译遵循 CC BY-SA 4.0 许可协议
我经常听到在编译 C 和 C++ 程序时我应该“始终启用编译器警告”。为什么这是必要的?我怎么做?
有时我也听说我应该“将警告视为错误”。我是不是该?我怎么做?
原文由 n. m. 发布,翻译遵循 CC BY-SA 4.0 许可协议
我曾经在一家制造电子测试设备的大型(财富 50 强)公司工作。
我小组的核心产品是一个 MFC 程序,多年来,它产生了数以百计的警告。在几乎所有情况下都被忽略了。
当错误发生时,这是一场可怕的噩梦。
在那个职位之后,我很幸运地被聘为一家新创业公司的第一位开发人员。
我鼓励所有构建都采用“无警告”策略,编译器警告级别设置得相当嘈杂。
我们的做法是使用 #pragma warning - push/disable/pop 来处理开发人员确信确实没问题的代码,以及调试级别的日志语句,以防万一。
这种做法对我们很有效。
原文由 Jim In Texas 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
为什么要启用警告?
众所周知,C 和 C++ 编译器 默认 不报告一些常见的程序员错误,例如:
return
来自函数的值printf
和scanf
系列中的参数与格式字符串不匹配这些可以被检测和报告,只是通常不是默认的;必须通过编译器选项明确请求此功能。
如何启用警告?
这取决于您的编译器。
Microsoft C and C++ compilers understand switches like
/W1
,/W2
,/W3
,/W4
and/Wall
.至少使用/W3
。/W4
和/Wall
可能会发出系统头文件的虚假警告,但如果您的项目使用这些选项之一编译干净,那就去吧。这些选项是相互排斥的。大多数其他编译器都理解
-Wall
、-Wpedantic
和-Wextra
之类的选项。-Wall
是必不可少的,其余的都是推荐的(请注意,尽管名称为-Wall
只启用最重要的警告,而不是 _全部_)。这些选项可以单独使用,也可以一起使用。您的 IDE 可能有办法从用户界面启用这些功能。
为什么我应该将警告视为错误?他们只是警告!
编译器警告表明您的代码中存在潜在的严重问题。上面列出的问题几乎总是致命的;其他人可能会也可能不会,但您希望编译失败 ,即使 结果是虚惊一场。调查每个警告,找到根本原因并修复它。在误报的情况下,解决它 - 也就是说,使用不同的语言功能或构造,以便不再触发警告。如果这被证明非常困难,请根据具体情况禁用该特定警告。
您不想只留下警告作为警告,即使它们都是误报。对于发出的警告总数少于 7 个的非常小的项目来说,这可能是可以的。此外,新警告很容易在大量熟悉的旧警告中丢失。不允许那样。只需使您的所有项目都能干净地编译。
请注意,这适用于程序开发。如果您以源代码形式向全世界发布您的项目,那么最好不要在 发布 的构建脚本中提供
-Werror
或等效项。人们可能会尝试使用不同版本的编译器或完全不同的编译器来构建您的项目,这可能会启用不同的警告集。您可能希望他们的构建成功。启用警告仍然是一个好主意,这样看到警告消息的人就可以向您发送错误报告或补丁。如何将警告视为错误?
这再次通过编译器开关完成。
/WX
适用于 Microsoft,大多数其他人使用-Werror
。无论哪种情况,如果产生任何警告,编译都会失败。这够了吗?
可能不是!随着优化级别的提高,编译器开始越来越仔细地查看代码,这种更仔细的审查可能会发现更多错误。因此,不要满足于自己的警告开关,在启用优化的情况下编译时始终使用它们(
-O2
或-O3
或 —317d134889d03763284c9c47267 或/O2
.