C:做{...}而(0)?

时间:2010-04-22 00:58:13

标签: c macros

  

可能重复:
  Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
  do { … } while (0) what is it good for?

我正在研究一些充满宏的C代码:

#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)

任何人都可以解释这个宏的作用,以及为什么需要do {} while(0)?那不就是执行一次代码吗?

4 个答案:

答案 0 :(得分:19)

do { stuff() } while(0);

正在做与stuff()完全相同的事情。那么有什么大不了的呢?问题在于宏的语法。假设我们将宏定义为:

#define SAFE_FREE(x) if ((x) != NULL) { free(x); x=NULL; }

然后,有两个问题。第一个是相对较小的:使用SAFE_FREE不再需要尾部分号。更重要的是,代码如:

if (...)
  SAFE_FREE(x)
else
   stuff();

将扩展为:

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

如上所述定义宏可以防止上述奇怪的行为,因为do { ... } while(0)就像没有分号的语句一样。

答案 1 :(得分:14)

do while是一种常见的约定,它使得宏需要像标准c函数那样的尾随半冒号。除此之外,它只是确保已释放的变量设置为NULL,以便将来任何释放它的调用都不会导致错误。

答案 2 :(得分:1)

do / while(0)背后的想法是你可以使用宏来使用函数调用而不会出现意外错误。

例如,如果您的代码如下:

if (today_is_tuesday())
    SAFE_FREE(x);
else
    eat_lunch();

而宏只是:

#define SAFE_FREE(x)  if (x) { free(x); x = 0; }

你会得到一个非常不同的结果。 do / while约定通过使其行为一致来避免这些错误。

答案 3 :(得分:1)

BTW在C++ Style and Technique FAQ Bjarne Stroustrup建议使用内联(模板)函数来执行“删除和null”

template<class T> inline void destroy(T*& p) { delete p; p = 0; }