带有 goto 的扩展 asm,包括来自 gcc 文档的示例,无法编译

Extended asm with goto, including an example from the gcc docs, fails to compile

某些使用 goto 限定符的扩展汇编语句无法使用 GCC 10.1.0 进行编译。具体来说,

int foo(int count)
{
  asm goto ("dec %0; jb %l[stop]"
            : "+r" (count)
            :
            :
            : stop);
  return count;
stop:
  return 0;
}

GCC 扩展 asm 文档 中的示例)无法编译并显示消息 expected ‘:’ before string constant。删除 "+r" (count)dec %0 允许它成功编译,但无论我在与 goto 标签相同的 asm 语句中提供输出操作数时尝试什么,它都会以同样的方式出错。

asm goto 不允许输出操作数。

这是 gnu 的决定。在来自 c-parser.c 的函数 c_parser_for_statement 中,您可以找到 :

/* For asm goto, we don't allow output operands, but reserve
the slot for a future extension that does allow them.  */

https://github.com/gcc-mirror/gcc/blob/releases/gcc-10/gcc/c/c-parser.c

然而,这种情况可能会改变,因为在 master 分支中,这条评论不再存在。

出现了current development GCC documentation which you are referencing applies to the latest trunk branches of GCC and doesn't apply to any of the official releases of GCC. Official releases of GCC do not as of this time support asm goto with any output or input/output constraints. You can see this on godbolt。最新的主干可以工作,但 10.2 和 10.1 不能。修复是等待 GCC 的下一个主要版本(版本 11.x);下载并编译最新的主干版本;修改您的内联程序集,使其不依赖于任何输出或 output/input 约束。

直到最近 documentation for GCC up to version 10.x 还这么说:

An asm goto statement cannot have outputs. This is due to an internal restriction of the compiler: control transfer instructions cannot have outputs. If the assembler code does modify anything, use the "memory" clobber to force the optimizers to flush all register values to memory and reload them if necessary after the asm statement.

可以在此 URL 找到正式版本的所有文档列表和当前的开发文档。当前的开发文档位于页面底部。根据经验,您应该查阅特定版本的 GCC 的文档。我相信所有 10.x 发布文档与 GCC 网页上最新 10.x 版本的文档相同。

CLANG/LLVM (11.0+) 的最新版本确实支持此功能,但这也是相对较新的添加。