如何判断计算goto语句是否被支持?

4

我正在编写一个字节码解释器,可以使用计算goto或正常的switch进行主指令分发循环。关键部分包含在一对宏中,可以定义为使用计算goto或不使用。

我希望根据编译器是否支持计算goto来决定默认使用哪种模式。有人知道如何确定吗?据我所知,它们适用于GCC和Clang,但我不想只是硬编码几个随机的编译器名称。


您也可以通过在MSVC中使用“default: __assume(0);”语句来实现消除边界检查的相同效果,告诉编译器这种情况永远不会发生。我怀疑还有其他直接向其他编译器提供相同提示的方法(GCC的__builtin_unreachable可能也可以作为替代方案)。 - doynax
3
@doynax,这并没有完全相同的效果。使用计算goto语句,您可以预先填充一个带有标签地址的数组,例如OCaml字节码解释器中的操作。 - SK-logic
@SK-logic:你说得对,他们正在使用线程化代码并为减少间接寻址付出了空间代价,我没有想到这一点。(你知道64位系统上Jumptbl_base偏移量是什么吗?似乎code_t总是一个完整的指针,因此他们似乎无法通过编码相对16/32位代码偏移来节省空间。) - doynax
算了,这正是他们正在做的事情。真正的问题是我应该感到印象深刻还是恐惧。 - doynax
@doynax,至少你应该对他们的基准结果感到印象深刻。这种方法在性能方面非常有效,通过一些预处理器技巧,它甚至看起来不那么可怕。虽然,OP的问题仍然存在- 没有优雅的方法来检测是否支持此扩展(我认为autoconf方法在任何合理的方式下都不算“优雅”)。 - SK-logic
1个回答

5

如果您正在使用像autoconf这样的工具,以下功能测试对我很有用:

AC_MSG_CHECKING([if ${CC-gcc} supports computed gotos])
AC_COMPILE_IFELSE(
  [AC_LANG_PROGRAM(
    [],
    [[
      void *my_label_ptr = &&my_label; /* GCC syntax */
      goto *my_label_ptr;
      return 1;
      my_label:
      return 0;
    ]])],
  [AC_MSG_RESULT(yes)
   AC_DEFINE(HAVE_COMPUTED_GOTOS, 1,
     [Define to 1 if the compiler supports computed gotos])],
  [AC_MSG_RESULT(no)])

如果编译器支持GCC语法,它将定义宏HAVE_COMPUTED_GOTOS

谢谢,这是一个有趣的方法,但我没有使用autoconf。 - munificent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接