_Noreturn в C11
Си — язык на котором я программирую редко, но всё же такое случается. Соответственно слежу что там появляется нового (кстати, есть ребята, которые понятия не имеют, что этот язык вообще развивается).
В относительно недавно вышедшей редакции
Смысла этого я не понимал,
Я noreturn никогда не пользовалась, но насколько я знаю он нужен, когда функция вообще не возвращает значение. В void функции можно сказать ’return;’
Noreturn-функции либо бросают исключения, либо говорят exitв какой-то момент. Если компилятор знает, что из функции возврата нет, то может сделать соответствующую оптимизацию.За Си не слежу, мне здесь C# полезнее, чем С.
Чуть подробнее об этом написано в описании атрибута «noreturn» компилятора gcc (там есть аналог в виде расширения языка) на примере функции fatal:
The noreturn keyword tells the compiler to assume that fatal cannot return. It can then optimize without regard to what would happen if fatal ever did return. This makes slightly better code. More importantly, it helps avoid spurious warnings of uninitialized variables.
The noreturn keyword does not affect the exceptional path when that applies:
a noreturn-marked function may still return to the caller by throwing an exception or calling longjmp.Do not assume that registers saved by the calling function are restored before calling the noreturn function.
В общем, примерно понятно, хотя, на мой взгляд, всё равно выглядит как микрооптимизация.
Комментарии 10
int foo()
{
if(a) return b;
else halt();
}
не соберётся. и нужно либо ставить фиктивный return в конце, либо объявлять halt с атрибутом noreturn. второй метод по мне выглядит изящней.
нет:non-void function [-Werror=return-type]
C:\>cat test.c
void halt(void);
int foo(int a,int b)
{
if(a) return b;
else halt();
}
C:\>g++ -Wall -Wextra -Werror -O3 -c -o «test.o» «test.c»
test.c: In function 'int foo(int, int)':
test.c:7:1: error: control reaches end of
}
^
cc1plus.exe: all warnings being treated as errors
C:\>cat test_nr.c
void halt(void) __attribute__((noreturn));
int foo(int a,int b)
{
if(a) return b;
else halt();
}
C:\>g++ -Wall -Wextra -Werror -O3 -c -o «test_nr.o» «test_nr.c»
это нестандартный noreturn, а я про стандартный _Noreturn
Комментарий для zg.livejournal.com:
Вот с дефольтными ключами:
Комментарий для Евгения Степанищева:
а зачем вы halt объявили как noreturn, а в теле функции написали return?
Чтобы показать варнинг о котором речь идёт.
так если неправильно _Noreturn пользоваться, конечно варнинг будет.
Почему