c++ - 为什么在 C/C++ 中交织 switch/for/if 语句是有效的?

标签 c++ c language-lawyer

<分区>

我正在阅读 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 标签,因此它们可以放在任何地方。

关于c++ - 为什么在 C/C++ 中交织 switch/for/if 语句是有效的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59608918/

相关文章:

c++ - 指针运算 : out of bound without dereferencing

c++ - 使用 Visual Studio 进行分析,在函数的右括号或左括号上包含较大的包含样本百分比? C++

如果参数之一是字符串,则 C++ 返回类型等于字符串

c - 来自用户的 n 个整数的中位数

c - 将 printf() 作为参数传递给自身 : printf ("%", printf ("%s", "something something"));

c++ - this-> 是否必须从派生类访问 Base<T> 标识符?

c++ - 错误 C2011 : 'XX' : 'class' type redefinition

c++ - 为 Ruby 使用 FFI 包装 C 函数

c - 我如何正确指向这段内存以将其视为我的结构?

c - C中thread_local对象初始化为0吗?