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 函数无效。
支持代码块并且仍然容忍类型转换的正确宏是什么?
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 函数无效。