C++ 为什么在C/C+中交织switch/for/if语句是有效的+;?
我正在阅读C++ 为什么在C/C+中交织switch/for/if语句是有效的+;?,c++,c,language-lawyer,C++,C,Language Lawyer,我正在阅读boost/asio/coroutine.hpp,无法理解boost\u asio\u CORO\u重新输入和boost\u asio\u CORO\u产量的实现。扩展形式 reenter (this) { yield .. yield .. } 似乎是交织在一起的switch/if/for语句。我想知道为什么这是有效的C代码?我写了一些类似的东西(如下所示),发现它是用gcc编译的 int main() { int a = 1; switch (a) case
boost/asio/coroutine.hpp
,无法理解boost\u asio\u CORO\u重新输入和boost\u asio\u CORO\u产量的实现。扩展形式
reenter (this) {
yield ..
yield ..
}
似乎是交织在一起的switch/if/for语句。我想知道为什么这是有效的C代码?我写了一些类似的东西(如下所示),发现它是用gcc编译的
int main() {
int a = 1;
switch (a)
case 0: if (1) a = 2;
else case 1: for (;;) {
case 3:
break;
}
return 0;
}
原因是它们不是结构化的控制流语句。相反,它们应该被视为静态分派的语法糖。分派意味着控制流被重定向,而静态意味着编译器知道它被重定向到哪里
所以你的代码
int a = 1;
switch (a)
case 0: if (1) a = 2;
else case 1: for (;;) {
case 3:
break;
}
return 0;
将被编译成大致相当于
int a = 1;
void *dest = dispatch(a, { case0_addr, case1_addr, case3_addr });
goto *dest;
case0_addr:
if (1) {
a = 2;
} else {
case1_addr:
for (;;) {
case3_addr:
goto case_end;
}
}
case_end:
return 0;
其中dispatch
是编译器运行的一个函数,用于发出静态分派所需的机器代码。由于所有分派值都是常量,并且编译器知道所有分派目标,因此它可以生成非常高效的机器代码
至于为什么它是合法的,我想原因是因为没有特别的理由它是非法的。如图所示,
case
语句只是goto标签,所以它们可以放在任何地方 从语法上讲,开关的主体只是一个语句(通常,但不一定是复合语句)
:
可能会贴上标签
:
例如:
switch(1) one: case 1: dothis();
如果它是复合语句,那么每个子语句也可以递归地标记。例如:
switch(x) {
if(1) one: case 1: dothis();
else case 0: orthis(); /*fallthru*/
three: case 3: three();
}
语法将大小写
/默认
-标签和常规标签视为相同,只有语义检查验证大小写
/默认
-标签是否位于开关
内
在实现方面,所有内容都编译成(平面)程序集
例如
被展平为(伪装配)
而且,没有理由不给这种平面代码中的任何东西贴上标签
代码>案例>代码> >代码>默认标签也像普通标签,除了它们通常也用于计算(通常)计算的跳。
这是一个骗局。如果你使用Boost,那么你在写C++,而不是C。所以你应该问为什么这是有效的C++,而不是为什么它是有效的C(即使答案可能非常相似)。。是否要包含一些原始代码?,这与此毫无关系。这是一个语法问题。不要乱贴标签。switch(1) one: case 1: dothis();
switch(x) {
if(1) one: case 1: dothis();
else case 0: orthis(); /*fallthru*/
three: case 3: three();
}
if(test) YesBranch; else ElseBranch;
IF_NOT_THEN_GOTO(test, PAST_YES_BRANCH)
YesBranch
goto PAST_NO_BRANCH;
NoBranch
PAST_NO_BRANCH:;