我经常听到有人说,在编译C和c++程序时,我应该“总是启用编译器警告”。为什么这是必要的?我怎么做呢?
有时我也听到我应该“把警告当作错误”。我应该吗?我怎么做呢?
我经常听到有人说,在编译C和c++程序时,我应该“总是启用编译器警告”。为什么这是必要的?我怎么做呢?
有时我也听到我应该“把警告当作错误”。我应该吗?我怎么做呢?
当前回答
处理警告不仅能写出更好的代码,还能让你成为更好的程序员。警告会告诉你一些今天对你来说微不足道的事情,但总有一天坏习惯会回来咬你的头。
使用正确的类型,返回该值,计算该返回值。花点时间思考“在这种情况下,这真的是正确的类型吗?”“我需要把这个还回去吗?”最重要的是;“这个代码在未来10年里还能移植吗?”
首先要养成编写无警告代码的习惯。
其他回答
警告包含了一些最熟练的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.
关闭或忽略警告,就像选择忽略那些比你更有经验的人的免费建议。这是一个傲慢的教训,当你飞得离太阳太近,翅膀融化了,或者发生记忆损坏错误时,这个教训就结束了。在这两者之间,我愿意随时从天上掉下来!
“将警告视为错误”是这一哲学的极端版本。这里的想法是解决编译器给您的每个警告——您听取每个免费建议并执行它。这对你来说是否是一个好的开发模式取决于你的团队以及你所开发的产品类型。这是僧侣可能有的苦行方式。对一些人来说,效果很好。对另一些人来说,则不然。
在我的许多应用程序中,我们不将警告视为错误。我们这样做是因为这些特定的应用程序需要在多个平台上编译,使用多个不同年代的编译器。有时我们会发现,如果在一个平台上修复一个警告,而不将其转化为另一个平台上的警告,实际上是不可能的。所以我们只是小心行事。我们尊重警告,但我们不会为它们竭尽全力。
别着急:你不必这么做,也没有必要。-Wall和-Werror是由代码重构狂人为自己设计的:它是由编译器开发人员发明的,目的是避免在用户端编译器或编程语言更新后破坏现有的构建。特性本身并不是什么,而是关于是否破坏构建的决定。
使用与否完全取决于您的喜好。我一直在用它,因为它能帮我改正错误。
一些警告可能意味着代码中可能出现语义错误或可能出现UB。例如;if()之后,一个未使用的变量,一个被局部变量掩盖的全局变量,或者有符号和无符号的比较。许多警告与编译器中的静态代码分析器或在编译时检测到的违反ISO标准有关,这“需要诊断”。虽然在特定情况下,这些事件可能是合法的,但大多数情况下,它们是设计问题的结果。
一些编译器,例如GCC,有一个命令行选项来激活“警告为错误”模式。这是一个很好的工具,如果残酷,教育新手。
其他的回答都很好,我不想重复他们说过的话。
One other aspect to "why enable warnings" that hasn't properly been touched on is that they help enormously with code maintenance. When you write a program of significant size, it becomes impossible to keep the whole thing in your head at once. You typically have a function or three that you're actively writing and thinking about, and perhaps a file or three on your screen that you can refer to, but the bulk of the program exists in the background somewhere and you have to trust that it keeps working.
如果你改变的某些东西给你看不见的东西带来了麻烦,你就会提醒自己。
例如Clang警告-Wswitch-enum。如果您在枚举上使用开关而漏掉了一个可能的枚举值,则会触发警告。您可能认为这是一个不太可能犯的错误:在编写switch语句时,您可能至少查看了枚举值列表。您甚至可能有一个IDE为您生成开关选项,不为人为错误留下任何空间。
六个月后,当您向枚举中添加另一个可能的条目时,这个警告才真正发挥作用。同样,如果您正在考虑所讨论的代码,那么您可能不会有问题。但是如果这个枚举用于多个不同的目的,并且它是用于您需要额外选项的其中一个目的,那么很容易忘记更新您六个月没有接触过的文件中的开关。
You can think of warnings in the same way as you'd think of automated test cases: they help you make sure that the code is sensible and doing what you need when you first write it, but they help even more to make sure that it keeps doing what you need while you prod at it. The difference is that test cases work very narrowly to the requirements of your code and you have to write them, while warnings work broadly to sensible standards for almost all code, and they're very generously supplied by the boffins who make the compilers.
忽略警告意味着您留下了草率的代码,这不仅会在将来给其他人带来问题,而且还会使您不太注意到重要的编译消息。
编译器输出越多,就越不会有人注意到。越干净越好。这也意味着你知道自己在做什么。警告是非常不专业、粗心和危险的。