Why `do { ...; exit(...); } while (0)` in C?

6
作为一个C语言的新手,我对下面的代码理解困难:
#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                           } while (0)

我了解到这个函数被 #define 定义的原因是为了覆盖一个现有的函数,但是使用 do ... while(0) 循环和无条件的 exit() 语句有什么意义呢?难道不能不使用循环结构来编写吗?

好问题,我也想知道!+1 - Kiril Kirov
很遗憾,标题重复检测器没有发现这个问题... - l0b0
3个回答

9

我认为这里有很多重复的内容。

do...while(0)技巧使您能够在不破坏任何东西的情况下在各种上下文中使用errExit

if(x) errExit(msg);
else return 1;

被翻译成:

if(x) do { ...; ...; } while(0);
else return 1;

如果省略do...while(0)的部分,那么你就无法可靠地添加分号。


2
为什么普通的大括号不能胜任这项工作? - Joe
不错!+1。这真的很聪明和巧妙。 - Kiril Kirov
1
啊,所以整个想法就是让结果代码在周围代码中只保留一个语句?很棒! - l0b0
@Joe 在这里阅读完整的答案 https://dev59.com/qXVC5IYBdhLWcg3w4Vb6#154138 - asheeshr
1
@Joe:不可以,因为分号的原因。正如 AshRj 所说,在其他地方提供的答案非常详尽。 - Benoit

2
假设宏中没有do { ... } while(0)循环,只有两个语句。那么,如果我写了以下内容:
if( foo() )
    errExit("foo!" );

我的有条件退出已经变成了无条件退出。

1

do { ... } while(0) 结构在宏函数中很常见,并且通常被认为是最佳实践,特别是对于包含多个语句的宏函数。它允许将其用作单个语句,因此不会有意外情况发生。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接