Почему noreturn / __ builtin_unreachable препятствует оптимизации хвостового вызова - PullRequest
2 голосов
/ 12 апреля 2019

Я пришел к выводу, что все основные компиляторы не будут выполнять оптимизацию хвостового вызова, если вызываемая функция не возвращает (т. Е. Помечена как _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; }

https://godbolt.org/z/PFhWKR

1 Ответ

7 голосов
/ 12 апреля 2019

Это намеренно, хотя, может быть спорным, так как это может серьезно повредить свойства использования стека;по этой причине я даже прибег к обману компилятора, чтобы думать, что функция, которая не может вернуть, может.Причина заключается в том, что многие функции noreturn * abort -подобны (или даже вызывают abort), и что, вероятно, кто-то, работающий с отладчиком, хочет видеть, откуда произошел вызов - информация, которая будет потерянахвостовой вызов.

Цитирования:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...