boost/asio/coroutine.hpp
,无法理解BOOST_ASIO_CORO_REENTER和BOOST_ASIO_CORO_YIELD的实现。 的扩展形式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; }
6.8:
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
可能带有标签6.8.1:
labeled-statement: identifier : statement case constant-expression : statement default : statement
示例:
switch(1) one: case 1: dothis();
如果是复合语句,则也可以递归地标记每个子语句。示例:
switch(x) { if(1) one: case 1: dothis(); else case 0: orthis(); /*fallthru*/ three: case 3: three(); }
[语法将case
/default
-标签和常规标签视为相同,只有语义检查才能验证case
/default
-标签在switch
内。在实现方面,所有内容都将编译为(平面)汇编。
例如
if(test) YesBranch; else ElseBranch;
展平为(伪汇编)
IF_NOT_THEN_GOTO(test, PAST_YES_BRANCH) YesBranch goto PAST_NO_BRANCH; NoBranch PAST_NO_BRANCH:;
并且没有理由不能标记这种平面代码中的任何内容。[
case
/default
标签也与常规标签一样,不同之处在于它们(也通常用于)计算的跳转。
所以您的代码
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
语句只是转到标签,因此可以将它们放置在任何位置。