可能重复:
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)
?那不就是执行一次代码吗?
答案 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; }