我发现,如果一个被调用的函数没有返回(即标记为_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(); }
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; }
答案 0 :(得分:7)
这是有意的,尽管可能会引起争议,因为它会严重损害堆栈使用属性;由于这个原因,我什至使欺骗编译器以为无法返回的函数可以。原因是许多noreturn函数类似于abort
(甚至调用abort
),并且运行调试器的某人可能希望能够看到调用从何处发生-信息被尾声弄丢了。
引用: