“do {free(x); x = NULL;} while(0);”之间的区别是什么?和“{free(x); x = NULL;}”

时间:2012-12-21 15:54:34

标签: c

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

这些宏之间有什么区别?

4 个答案:

答案 0 :(得分:12)

如果您的问题是关于宏中的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技术的原因 - 使其在这种上下文中使用普通函数正确且统一地工作。

P.S。作为旁注,所有这些技术的目的是将一组多个语句转换为一个复合语句。在您的特定情况下,free(x); x = NULL;序列可以重新实现为表达式(free(x), x = NULL),这消除了对任何多语句宏技术的需要,即此

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

也会奏效。但这是个人偏好的问题。

答案 1 :(得分:5)

实际上,C-wise没有区别。

原因是你在:

中加入了一个尾部分号
#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
    ...

......都是不合格的。

答案 2 :(得分:2)

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

定义此宏的更好方法是

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

(没有尾随分号。)

答案 3 :(得分:0)

这:

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

只执行一次,所以它与:

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

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

相关问题