为什么noreturn / __ builtin_unreachable阻止尾部调用优化

Nik*_*zev 2 c c++ noreturn

我发现,如果一个被调用的函数没有返回(即标记为_Noreturn/ [[noreturn]]__builtin_unreachable()在调用后有一个),那么所有主要的编译器都不会进行尾部调用优化。这是预期的行为,而不是错过的优化吗?如果是,为什么?

范例1:

#ifndef __cplusplus
#define NORETURN _Noreturn
#else
#define NORETURN [[noreturn]]
#endif

void canret(void);
NORETURN void noret(void);

void foo(void) { canret(); }
void bar(void) { noret(); }
Run Code Online (Sandbox Code Playgroud)

C:https//godbolt.org/z/pJfEe- C ++:https//godbolt.org/z/-4c78K

范例2:

#ifdef _MSC_VER
#define UNREACHABLE __assume(0)
#else
#define UNREACHABLE __builtin_unreachable()
#endif

void f(void);

void foo(void) { f(); }
void bar(void) { f(); UNREACHABLE; }
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/PFhWKR

R..*_*R.. 7

这是有意的,尽管可能会引起争议,因为它会严重损害堆栈使用属性。由于这个原因,我什至使欺骗编译器以为无法返回的函数可以。原因是许多noreturn函数都是类似abort的(甚至是call abort),并且运行调试器的某人可能希望能够看到调用发生的位置,这些信息会因尾部调用而丢失。

引文:

  • 这是有道理的。这是事实信息还是基于意见? (2认同)