Ara*_*hor 1 c macros scope curly-braces
我最近看到一段C代码,包括以下样式的宏:
#define TOTO() \
do { \
do_something(); \
do_another_something(); \
} while (0)
Run Code Online (Sandbox Code Playgroud)
我起初想知道do while (0)
这里的目的,但是这个答案向我解释:如果宏只是在一个if
或else
没有花括号之后使用,就像这样:
if (something)
TOTO();
else
do_something_else();
Run Code Online (Sandbox Code Playgroud)
所以这里没有do while (0)
语句,代码将扩展为:
if (something)
do_something();
do_another_something();
else
do_something_else();
Run Code Online (Sandbox Code Playgroud)
这在语法上是错误的,因为else
它不再直接跟随if
范围.
但是我认为它可以通过在自己的范围内声明宏来实现,而不必do while
围绕它,所以我用大括号测试了相同的代码.我的整个代码如下所示:
#include <stdio.h>
#define HELLO_WORLD() \
{ \
printf("hello "); \
printf("world!\n"); \
}
int main(int argc, char** argv)
{
if (argc == 1)
HELLO_WORLD();
else
fprintf(stderr, "nope\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是GCC给了我以下错误:
错误:'else'没有前一个'if'
但是,该main
函数的代码应扩展为:
if (argc == 1)
{
printf("hello ");
printf("world!\n");
}
else
fprintf(stderr, "nope\n");
return 0;
Run Code Online (Sandbox Code Playgroud)
这是有效的.
那我在这里错过了什么?
它是宏之后的分号.
宏被扩展为此:
if (argc == 1)
{
printf("hello "); \
printf("world!\n"); \
};
else // HERE, SYNTAX ERROR
fprintf(stderr, "nope\n");
return 0;
Run Code Online (Sandbox Code Playgroud)
由于if
-statement 的主体和-clause 之间不应该有分号else
,因此这是一个语法错误.
OTOH,a do
- while
循环允许(并且需要)分号.
只需打印真实的预处理器输出,就可以轻松避免对编译器输出的误解.这可以通过使用
-E
切换gcc
.来自man 1 gcc
:-E在预处理阶段后停止; 不要正确运行编译器.输出采用预处理源代码的形式,发送到标准输出.
cpp
可执行文件的形状.感谢
- @dhke纠正错误发生在.
- @kakeh提供预先查看预处理器输出的建议.