#define FREE1(x) do { free(x); x = NULL; } while (0);
#define FREE2(x) { free(x); x = NULL; }
这些宏之间有什么区别?
答案 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; }
但是在汇编代码中有一个更多的分支。即使现代编译器可能会对它进行优化,所以即使生成的汇编代码也是如此,所有概率都是相同的。