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

这些宏有什么区别?

4

4 回答 4

12

如果您的问题是关于do/while宏中的技巧,那没有区别,因为您显然在第一个宏定义中犯了错误,这完全违背了技巧的目的。你把;. whole (0)正确的实现绝对应该在第一个宏中包含;after 。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在多语句宏中使用该技术的原因 - 使其在此类上下文中与普通函数正确且一致地工作。

PS 作为旁注,所有此类技术的目的是将一组多个语句转换为一个复合语句。在您的特定情况下,free(x); x = NULL;可以将序列重新实现为单个表达式(free(x), x = NULL),从而无需任何多语句宏技术,即

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

也会起作用。但这是个人喜好的问题。

于 2012-12-21T16:02:55.697 回答
5

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

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

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

此处描述了您通常要使用的原因do...while(0),是您通常希望在块中使用它:if...else

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

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

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

...和...

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

...都是不正确的。

于 2012-12-21T16:04:20.820 回答
2

两者都是解决C/C++ 宏中的 Do-While 和 if-else 语句中讨论的分号问题的半生不熟的尝试。

定义此宏的更好方法是

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

(没有尾随分号。)

于 2012-12-21T16:05:22.043 回答
0

这:

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

只执行一次,因此它与以下内容相同:

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

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

于 2012-12-21T16:01:09.100 回答