我发现,如果一个被调用的函数没有返回(即标记为_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)
这是有意的,尽管可能会引起争议,因为它会严重损害堆栈使用属性。由于这个原因,我什至使欺骗编译器以为无法返回的函数可以。原因是许多noreturn函数都是类似abort的(甚至是call abort),并且运行调试器的某人可能希望能够看到调用发生的位置,这些信息会因尾部调用而丢失。
引文:
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |