我正在阅读 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;
}
原因是因为switch statements不是结构化的控制流语句。相反,它们应该被视为静态分派(dispatch)的语法糖。 Dispatch 意味着控制流被重定向,而 static 意味着编译器知道它被重定向到哪里。
所以你的代码
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
是编译器运行的函数,用于发出静态分派(dispatch)所需的机器代码。由于所有调度值都是常量,并且编译器知道所有调度目标,因此它可以生成非常高效的机器代码。
至于为什么合法,我猜是因为没有特别的理由不合法。如图所示,case
语句只是 goto 标签,因此它们可以放在任何地方。