Подтвердить что ты не робот

Использование _Noreturn в C11

Возможный дубликат:
В чем смысл атрибута Noreturn?

C11 ввел атрибут > Noreturn, чтобы указать, что функция никогда не возвращается.

За исключением значения документации в исходном коде, какие другие преимущества предоставляет атрибут и почему его можно использовать?

4b9b3361

Ответ 1

Если функция безоговорочно вызывает функцию _Noreturn, компилятор сможет понять, что:

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

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

Там может быть и другая доступная оптимизация - поскольку функция никогда не возвращается, нет необходимости нажимать адрес возврата в стеке, сохранять состояние регистров и т.д., все, что необходимо, - это передать аргументы и выполнить jmp до начала функции, не беспокоясь о возврате и очистке после возврата. Но, конечно, поскольку вызов одноразовый, производительность для сжатия здесь в основном незначительна.

Ответ 2

__attribute__((noreturn)) или _Noreturn полезен для таких функций, как die():

static __attribute__((noreturn)) void die(const char *fmt, ...) {
     /* print a formatted error message and exit  */
     exit(EXIT_FAILURE);
}
/* And let say in main() you would want to exit because of an error but unforunately GCC complains about return value.  */
int main() 
{
    if (!whatever)
         die("a nasty error message goes here\n");
}

И также используется для оптимизации, как указано.

Ответ 3

Это позволяет делать дополнительные оптимизации компилятором. Посмотрите здесь в атрибуте GCC noreturn, который он поддерживает некоторое время (семантика, вероятно, такая же)