【问题标题】:How to check/detect an 'if' clause without curly braces?如何检查/检测没有花括号的“if”子句?
【发布时间】:2013-03-27 17:25:45
【问题描述】:

在 C/C++ 代码项目中,我想找到所有不使用大括号的 if/else 语句。是否有任何编译器检查或实用程序可以找到它们?

主要问题是我想重新定义一些调试宏以避免在某些情况下进行跟踪评估(有谁知道其他解决方案吗?)。而且我需要找到它们以避免“dangling-else problem”,正如"if" block without curly braces makes subsequent "else if" nested中指出的那样

代码片段:

修改前:

DEBUG GET_DEBUG_DST(DEBUG_LEVEL_DEBUG).nospace() << DEBUG_PREFIX << __PRETTY_FUNCTION__

现在我们将使用没有大括号的if

DEBUG if (getDebugmode(DEBUG_LEVEL_DEBUG)) GET_DEBUG_DST(DEBUG_LEVEL_DEBUG).nospace() << DEBUG_PREFIX << __PRETTY_FUNCTION__

有问题的代码示例:

if (my condition)
    DEBUG << "hi there";
else
    {some more code;}

【问题讨论】:

  • 首先,将这种调试日志替换为合理且理智的东西会更好。
  • 尝试创建编译错误
  • @H2CO3 我知道,但我没有启动它,我必须处理它。
  • @Alon 我试图想出一种方法来引发编译错误,但还没有找到任何方法。有什么想法吗?
  • 您可以使用 if\s*\(.*\)\s*^{ 或类似形式的正则表达式,但正如其他人所说,您应该修复调试代码而不是其余代码

标签: c++


【解决方案1】:

坏主意。

用途:

#define debug(x) do { if (DEBUG_LEVEL) print_stuff(x); } 而(0)

这避免了这个问题。

【讨论】:

  • 问题是宏的使用,目前是DEBUG
  • 你必须找到所有损坏的代码。不确定是否有一种简单的方法可以做到这一点......
【解决方案2】:

我想在 c/c++ 代码项目中找到所有不使用大括号的 if/else 语句。是否有任何编译器检查或实用程序可以找到它们?

这听起来像x-y problem。如果您尝试使用不会使 if 语法无效的空操作替换 DEBUG 宏,您可以使用:

#ifdef DEBUG_ENABLED
#define DEBUG GET_DEBUG_DST(DEBUG_LEVEL_DEBUG).nospace() << DEBUG_PREFIX // ...
#else
#define DEBUG do {;} while(false); /##/
#endif

在这种情况下,DEBUG 将是一个有效操作(不会因为 if 块中的任何内容而使 else 无效),并且同一行上的任何内容(调试消息数据)都将评估为:

if (my condition)
    do {;} while(false); // << "hi there";
else
    {some more code;}

这有一个缺点,就是不允许多行调试 cmets:

if (my condition)
    DEBUG << "hi there"
        << "some more data on a different line"; // causes error if DEBUG is no-op
else
    {some more code;}

【讨论】:

  • 这解决了编译时的问题,解决方法类似,但目的是在运行时修改跟踪,所以我需要使用if()。
  • 不幸的是,就像许多预处理黑客一样,这不起作用。 宏扩展之前删除注释,该宏扩展适用于预处理器标记而不是源字符。所以在处理之后,你最终会得到两个 / 标记,给出一个语法错误。
【解决方案3】:

只需反转逻辑,将活动部分放在else中 分支:

#define DEBUG if( !getDebugmode( DEBUG_LEVEL_DEBUG ) )              \
        ;                                                           \
    else                                                            \
        GET_DEBUG_DST( DEBUG_LEVEL_DEBUG ).nospace()                \
            << DEBUG_PREFIX << __PRETTY_FUNCTION__

由于if 有匹配的else,因此无法接听 任何额外的else

【讨论】:

  • 很好的解决方案,但由于 OP 似乎假设 if 需要在 #define 内,因此值得注意的是,情况并非如此,还有其他解决方案 - 一个会要有一个代理流对象,其中重载的operator&lt;&lt; 接管调试模式的检查,而宏只是#define DEBUG get_stream_proxy() &lt;&lt; DEBUG_PREFIX &lt;&lt; __PRETTY_FUNCTION__ ...
  • @KonradRudolph 我认为是那个,但我放弃了它,因为它不会避免在运算符之后评估所有代码
  • @kikeenrique 我自己通常使用代理解决方案。如果操作正确,&lt;&lt; 之后的 表达式 将被计算,但除非跟踪处于活动状态,否则不会进行任何转换。通常情况下,表达式是相当微不足道的,真正的成本是转换,但人们永远不知道。
猜你喜欢
  • 1970-01-01
  • 2023-01-16
  • 2012-05-03
  • 2013-10-30
  • 2017-06-14
  • 1970-01-01
  • 2012-02-02
  • 2012-01-18
相关资源
最近更新 更多