do...while(0) 定义块并支持类型转换

do... while(0) define block and support for type cast

支持代码块并且仍然容忍类型转换的正确宏是什么?

if (fooisneeded)
    (void)foo();

#define foo() do {foo_subpart1(); foo_subpart2;} while(0): 不允许类型转换

#define foo() 0; do {foo_subpart1(); foo_subpart2;} while(0): 会在无手镯中破损 if/<loop>

使用 (void) foo() 对宏来说是不可能的,因为该构造依赖于 return 类型,而宏就其本质而言是没有的。宏也不了解 C 语义或语法,因此计算 return 类型已经不可能了。

这有什么意义呢?将函数表达式转换为 (void) 旨在告诉编译器 "you ain't gonna need it." 宏甚至 return 都没有值,它只是进行文本替换。你不需要 "you ain't gonna need it."

改用 inline 函数或仅使用函数。如果你需要做这类事情,那么宏是错误的工具。

非标准的,如果需要是宏,可以使用statements-as-expression 扩展(至少在 gcc、tcc 和 clang 中可用)

#define foo() ({ for(;;);  }) 
//equivalent to a func returning void or whatever the type of
//the last statement before }) is
int main()
{
    (void)foo();
}

否则,inline/static 函数无效。