有没有办法让gcc或clang在缺少'else'时发出警告?

3
我希望编译器能够在我没有处理每个if语句的else条件时发出警告。这在clang或gcc中存在吗?
为了澄清,我不是想让所有源代码都开启此功能。然而,有时候整个文件或大片代码区域都需要仔细思考每个else块的设计。因此,我真正在寻找的是能够打开和关闭的pragma,以便在几千行非常重要的代码中启用和禁用此功能。可将其视为自动化代码审查或静态分析工具。
说编译器无法执行此操作,因为它是合法的...是实践中不存在的问题。我见过的每个C / C ++编译器都会很乐意针对完全符合语法和语义规范的代码发出大量警告。(例如,在gcc中,-Wunused-value,-Wunused-label,-Wunreachable-code等...)

7
健康比例的“if”语句没有“else”从句。所谓健康比例是指在30%到70%之间。发出这样的警告是愚蠢的,会导致无意义的代码膨胀(在每个“if”从句的末尾添加“else {}”)和噪音。 - Nicol Bolas
我将在我的动机问题中添加一个澄清的说明。 - Will Bradley
任何包含 throwbreakreturncontinueif 语句都有一个隐式的 else:即条件之后的代码。在此要求显式的 else 语句是不合适的。 - edA-qa mort-ora-y
我不确定这些关键字如何影响else,因为运行在if块中的代码将要求else块中的代码不运行,反之亦然。 - Will Bradley
3个回答

9
如果你真的想要这个,我建议下载Cppcheck并添加一个检查。Cppcheck使用简单的基于文本的匹配来检查规则集。警告缺少else子句应该是相当直接的。
我在这里的missing-else分支中实现了一个原型检查"缺少else":https://github.com/ghewgill/cppcheck/tree/missing-else。这通过了自己的测试,但由于新的意外样式警告(在其他合法代码上),它会失败很多其他测试。

这可能是我得到想要的唯一途径,但是投入自己的时间来开发这个工具对我来说不值得,所以从某种意义上说,这不是一个可接受的答案。看起来真正的答案是“不行”。 :-( - Will Bradley
@GregHewgill:感谢您推荐使用Cppcheck。非常棒。 - Will Bradley
@WillBradley:我在这里的missing-else分支中实现了一个原型检查“缺少else”的功能:https://github.com/ghewgill/cppcheck/tree/missing-else。它通过了自己的测试,但由于新的意外样式警告(在本来合法的代码上),它未能通过许多其他测试。希望你觉得这个有用。 - Greg Hewgill
谢谢 Greg!有没有办法使用 #pragmas 来启用/禁用 CppCheck 发出的此检查或其他检查? - Will Bradley
所以,我真的很好奇这对你有什么帮助。我的修补过的cppcheck能否识别出你缺少的“else”子句? - Greg Hewgill
显示剩余4条评论

3

编译器无法判断一个简单的if()是否是有效的条件语句。
编译器会警告可能存在的语义错误,但并不意味着提供调试功能。
如果需要这样的功能,您需要依赖一些专门用于此目的的代码分析工具。


1
他在询问警告,而不是错误。警告对于合法的事情是允许的,比如不引用变量等。编译器肯定可以对这些事情发出警告。 - Nicol Bolas
@NicolBolas:警告允许用于合法的事情同意。这是编译器根据用户通常在使用它们时犯错的经验而提供的额外功能。一个没有else语句的if几乎不算是这样一个特性。如果编译器必须提供这样的特性,那么列表可能是无穷无尽的。 - Alok Save
没错,这个列表可能是无穷无尽的。但是,这个建议并不那么荒谬。通常最好的做法是至少有一个 else 块,并在其中加上注释,说明 /* 我考虑过这个情况,它应该继续执行或者什么都不做 */。 - Will Bradley
2
@WillBradley:谁说这是好的编程习惯?在大多数情况下,从条件的本质上很明显就应该继续执行。添加注释和else子句只会占用空间。 - Nicol Bolas
好的。对不起,你是正确的。这并不总是最好的做法。我只是在强调有时候强制开发人员(包括自己)有意识地处理else条件是非常宝贵的。 - Will Bradley

0

我担心这样的检查只会引起大量警告,因为很多代码都没有使用else子句。但是如果你只想检查你的代码,你可以使用这些小宏:

#define IF
#define THEN ?
#define ELSE :    

那么你只需要像这样编写代码:

int foo(bool flag)
{
    return IF(flag) THEN 0 ELSE -1;
}

当然这是个不好的主意。


1
猜猜看?它们解决了这个问题,如果缺少ELSE分支,则会生成错误。 - user529758
3
这还远远不够通用,无法代替 if/else - GManNickG
是的,在这种情况下,它会产生大量警告,但我希望如此。正如我在修改后的问题中提到的那样,我不希望在整个程序中都这样做,只想在某些翻译单元中,或者理想情况下在某些#pragma区域中这样做。 - Will Bradley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接