【问题标题】:How can I find if and for statements without braces?如何找到没有大括号的 if 和 for 语句?
【发布时间】:2019-12-10 14:18:08
【问题描述】:

我正在查看一个项目,其中一些 if 和 for 语句没有相关的括号,如下所示:

if(condition)
  single_line_statement;
for(int i=0;i<10;i++)
  single_line_statement;

我想找到这些语句!

但是,由于存在具有两种不同括号样式的代码,这使得这变得具有挑战性:

if(condition){
   stuff;
}

和

if(condition(a) && condition(b))
{
  stuff;
}

以及复杂的语句,例如(注意嵌套的括号):

for (auto const &x : y)
{
    for (auto const &m : ted.bob())
    {
        if (m.n(o) != 0)
        {
            p[q] = true;
        }
        r["s"].push_back(rn.t(u));
    }
}

如何找到不带括号的if 和for 语句?

【问题讨论】:

    标签: c++ command-line


    【解决方案1】:

    为了解决这个问题,我创建了一个方便的花花公子脚本:

    #!/bin/bash
    find . -name '*.h' -o -name '*.cpp' | #Find all C++ files
      xargs pcregrep -A 1 -nHM '\b(?:if|for)\s*(\(([^()]++|(?1))*\))(?!.*{|.*\n.*{)'
    

    这会查找所有 C++ 文件,然后使用 Perl 兼容正则表达式将每个文件的内容作为一个长行来检查。此表达式使用递归(?1) 来提取if 和for 语句之后的(condition),并使用. 字符来匹配不是换行符的字符,并使用\n 常量来匹配换行符。 Negative-lookahead (?!...) 用于查找没有大括号的行。

    正则表达式可以在线测试here。

    输出如下:

    ./dir1/file1.cpp:845:        if (!a)
    ./dir1/file1.cpp-846-            std::cout << "a not found!" << std::endl;
    --
    ./dir2/file2.cpp:20:    if (b == NULL)
    ./dir2/file2.cpp-21-        throw std::runtime_error("b was NULL");
    

    由于脚本实际上并不解析 C++,因此在某些情况下它会出现异常。例如,它会错过这个:

    if (condition) // An example {
      statement;
    

    This answer 利用clang-tidy 提供完整的检查,代价是必须将clang-tidy 合并到自己的构建系统中。

    【讨论】:

    • 您可以将 find 缩短为:find -name '*.h' -o -name '*.cpp'
    • 不幸的是,很容易找到您的正则表达式不起作用的示例。虽然这在简单的情况下就足够了。
    • 如果括号是条件后面的注释的一部分,则正则表达式会产生误报
    • @Richard 我不需要,不幸的是正则表达式无法解析 C++ 语法。正如我所说,这在简单的情况下就足够了,但恐怕不可能在 100% 的情况下做到这一点。
    • 我没有说别的,只是不想让一些人觉得你的脚本在所有情况下都可以工作(或者有可能让它修复你的正则表达式)
    【解决方案2】:

    我使用vera++ 来验证我的项目中的代码是否符合特定的样式规则。

    Vera: https://bitbucket.org/verateam/vera/wiki/Rules  
    Rule: T019 Control structures should have complete curly-braced block of code
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 2023-01-16
      • 1970-01-01
      • 2014-11-11
      相关资源
      最近更新 更多