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

dev*_*per 3 c

#define FREE1(x) do { free(x); x = NULL; } while (0);
#define FREE2(x) { free(x); x = NULL; }
Run Code Online (Sandbox Code Playgroud)

这些宏有什么区别?

AnT*_*AnT 12

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

现在这段代码无法编译

if (condition)
  FREE2(arg);
else
  /* something else */;
Run Code Online (Sandbox Code Playgroud)

此代码也不会编译

do 
  FREE2(arg);
while (condition);
Run Code Online (Sandbox Code Playgroud)

do/while技术的关键是使这个代码编译.但FREE1由于前面提到的错误,它不能用你的宏编译.

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

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

然后第一个宏将在上面的代码示例中完美地工作.这实际上是人们do/while在多语句宏中使用该技术的原因- 使其在这种情况下使用普通函数正确且统一地工作.

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

#define FREE3(x) (free(x), x = NULL)
Run Code Online (Sandbox Code Playgroud)

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


net*_*der 5

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

原因是你在下面包括一个尾随的分号:

#define FREE1(x) do { free(x); x = NULL; } while (0);
Run Code Online (Sandbox Code Playgroud)

您通常需要使用的原因do...while(0)这里描述的,是你一般要在使用它if...else的块:

if (...)
    FREE(x);
else
   ...
Run Code Online (Sandbox Code Playgroud)

但是使用上面的用法和宏:

if (...)
   do { free(x); x = NULL; } while (0);;
else
   ...
Run Code Online (Sandbox Code Playgroud)

...和...

if (...)
    { free(x); x = NULL; };
else
    ...
Run Code Online (Sandbox Code Playgroud)

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