【问题标题】:what is the difference between "do { free(x); x = NULL; } while (0);" and "{ free(x); x = NULL; }"“do { free(x); x = NULL; } while (0);”有什么区别?和“{ free(x); x = NULL; }”
【发布时间】:2012-12-09 05:09:29
【问题描述】:
#define FREE1(x) do { free(x); x = NULL; } while (0);
#define FREE2(x) { free(x); x = NULL; }

这些宏有什么区别?

【问题讨论】:

  • no 不是重复的,这是另一个问题
  • 您刚刚发布了两个相同的问题吗?
  • @CarlNorum - 最初的问题不包括第二个宏周围的大括号。如果您查看该问题的答案,添加大括号似乎可以解决两个宏之间的问题。
  • 确实,这不是同一个问题。请重新打开它
  • 这是什么问题? “有什么区别”应该是什么意思?是不是像“找10个不同”的游戏?第一个宏以d 开头,而第二个宏没有。这是您正在寻找的答案吗?

标签: c


【解决方案1】:

如果您的问题是关于宏中的do/while 技巧,那没有区别,因为您显然在第一个宏定义中犯了一个错误,这完全违背了该技巧的目的。您将; 放在whole (0) 之后。正确的实现绝对应该在第一个宏中的while (0) 之后有;。这就是do/while 技巧的重点。

现在这段代码将无法编译

if (condition)
  FREE2(arg);
else
  /* something else */;

这段代码也不会编译

do 
  FREE2(arg);
while (condition);

do/while 技术的重点是让这段代码编译。但由于上述错误,它也不会与您的 FREE1 宏一起编译。

但是,如果你正确定义了第一个宏

#define FREE1(x) do { free(x); x = NULL; } while (0)
// No `;` at the end!!!

那么第一个宏将在上述代码示例中完美运行。这实际上是人们在多语句宏中使用do/while 技术的原因 - 使其与此类上下文中的普通函数正确一致地工作。

附:作为旁注,所有这些技术的目的是将一组 multiple 语句转换为一个复合语句。在您的特定情况下,free(x); x = NULL; 序列可以重新实现为 single 表达式(free(x), x = NULL),这样就不需要任何多语句宏技术,即这个

#define FREE3(x) (free(x), x = NULL)

也可以。但这是个人喜好问题。

【讨论】:

    【解决方案2】:

    对于解决Do-While and if-else statements in C/C++ macros 中讨论的分号问题,两者都是半生不熟的尝试。

    定义此宏的更好方法是

    #define FREE3(x) do { free(x); x = NULL; } while (0)
    

    (没有尾随分号。)

    【讨论】:

      【解决方案3】:

      实际上,C 方面没有区别。

      原因是您在以下内容中包含了一个尾随分号:

      #define FREE1(x) do { free(x); x = NULL; } while (0);
      

      您通常要使用do...while(0) 的原因是described here,是您通常希望在if...else 块中使用它:

      if (...)
          FREE(x);
      else
         ...
      

      但是有了上面的用法和宏:

      if (...)
         do { free(x); x = NULL; } while (0);;
      else
         ...
      

      ...和...

      if (...)
          { free(x); x = NULL; };
      else
          ...
      

      ...都是不正确的。

      【讨论】:

      • 除了您提到的语法原因之外,do...while(0) 构造通常用于允许在块内部使用break 以避免goto 和/或代码重构。
      【解决方案4】:

      这个:

      #define FREE1(x) do { free(x); x = NULL; } while (0);
      

      只执行一次,所以它与:

      #define FREE2(x) { free(x); x = NULL; }
      

      但是在汇编代码中有一个更多的分支。即使现代编译器可能会对其进行优化,所以在所有概率下,即使生成的汇编代码也将是相同的。

      【讨论】:

        猜你喜欢
        • 2017-04-02
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        相关资源
        最近更新 更多