C:do {...} while(0)?[副本]

3pvhb19x  于 2023-04-29  发布在  其他
关注(0)|答案(4)|浏览(120)

此问题已在此处有答案

13年前就关门了

可能重复:

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)?那不是只执行一次代码吗

tjvv9vkg

tjvv9vkg1#

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();

请注意,else现在如何匹配错误的if语句。这完全改变了程序流程,即使它在源代码中看起来不像那样。
如上所述定义宏可以防止上面的奇怪行为,因为do { ... } while(0)就像没有分号的语句一样。

eyh26e7m

eyh26e7m2#

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

qojgxg4l

qojgxg4l3#

顺便说一句,关于C++风格和技术的常见问题解答Bjarne Stroustrup建议使用内联(模板)函数来执行“删除和空”

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

yyyllmsg4#

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约定通过使其行为一致来避免这些错误。

相关问题