GCC:__atomic_always_lock_free 使用 -O3 编译,但不使用 -O0

GCC: __atomic_always_lock_free compiles with -O3, but not with -O0

示例代码:

int *s;

int foo(void)
{
  return 4;
}

int bar(void)
{
  return __atomic_always_lock_free(foo(), s);
}

调用:

$ gcc t0.c -O3 -c
<nothing>

$ gcc t0.c -O0 -c
t0.c:10:10: error: non-constant argument 1 to '__atomic_always_lock_free'

有什么想法吗?

相关:https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html.

这似乎并不奇怪。您链接的文档说“size 必须解析为 compile-time 常量”,因此可以预期您在传递 foo() 时可能会出错。但是,如果 GCC 能够在编译时确定表达式的值,那么它通常会将其视为 compile-time 常量,即使它不符合语言对常量表达式的基本定义。这可能被认为是一个扩展,并且在 6.6p10 的 C17 标准中明确允许。

优化级别与编译器在编译时试图评估表达式的尝试有关。关闭优化后,它所做的只是标准要求的基本常量折叠(例如 2*4)。启用优化后,您将受益于其完整的常量传播传递以及函数内联。

所以本质上,在 -O0 下,编译器不会注意到 foo() 总是 returns 相同的值,因为你已经禁用了允许它的优化得出那个结论。对于 -O3 它确实如此,因此它接受它作为一个常数。