C/C++在if/for后面没有花括号,如何进行代码检查?

6
有没有办法通过代码检查或者使用sed/regexp来摆脱这些麻烦的情况呢?比如在if/for语句后只有一行代码,没有花括号,像这样:
if(condition)
    return;

为什么我想要摆脱这个的参考 - 在这个帖子中给出了很多原因:

使用大括号(即{})进行单行if或循环有什么用途?

我维护一些遗留代码,并处理其他人的一些未完成代码,有时会在调试时遇到这种代码风格像绊脚石一样的情况:

if(condition_for_early_return)
    LOG("Im here")   // surprise surprise, I just broke control logic
    return;

另外,我看过像这样的代码:

if(condition)
<tabs>   do_smth();
<spaces> do_smth_else();

当然,如果只包含第一个do_smth(),编译器不会混淆。但是由于do_函数在视觉上对齐,我想知道这是预期行为还是在这个旧代码中从未发现的错误。
我知道cppcheck无法捕捉到这些情况-已经尝试过了。 你有没有办法自动找到这些陷阱?

1
但是由于do_函数在视觉上都对齐,这是另一个永远不要使用制表符进行缩进的原因:混淆实际意图。 - Andrew Henle
3个回答

11

GCC有以下功能:

-Wmisleading-indentation (仅适用于C和C++)

当代码的缩进不反映块结构时发出警告。具体来说,对于带有保护语句但未使用花括号的if、else、while和for子句,后面跟着一个没有保护的语句且缩进相同,会发出警告。

在下面的示例中,“bar”函数调用的缩进误导性地表明它受“if”条件保护。

  if (some_condition ())
    foo ();
    bar ();  /* Gotcha: this is not guarded by the "if".  */

对于混合使用制表符和空格的情况,警告会使用-ftabstop=选项来确定语句是否对齐(默认为8)。
对于涉及多行预处理器逻辑的代码,例如以下示例,不会发出警告。
  if (flagA)
    foo (0);
#if SOME_CONDITION_THAT_DOES_NOT_HOLD
  if (flagB)
#endif
    foo (1);

警告不会在 #line 指令之后发出,因为这通常表示自动生成的代码,并且不能对指令引用的文件的布局做出任何假设。
请注意,在 C 和 C++ 中,此警告由 -Wall 启用。

另外,clang-format 提供了:

-InsertBraces (布尔值) clang-format 15

在 C++ 中的控制语句(if、else、for、do 和 while)后插入大括号, 除非这些控制语句位于宏定义内部或者大括号将包含预处理指令。

但是也会发出警告:

将此选项设置为 true 可能会导致代码格式不正确,因为 clang-format 缺乏完整的语义信息。 因此,在使用此选项进行代码更改时应格外小心。


4

2

Clang-tidy实际上为此提供了一个检查,如果我记得正确,它还可以为您自动修复问题(当然,您应该手动检查所有更改并确保它们是正确的)


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