_Noreturn в C11

Си — язык на котором я программирую редко, но всё же такое случается. Соответственно слежу что там появляется нового (кстати, есть ребята, которые понятия не имеют, что этот язык вообще развивается).

В относительно недавно вышедшей редакции Си-11 мне всё было понятно, кроме ключевого слова «_Noreturn» — им теперь предлагается маркировать функции из которых нет возврата (например, они вызвали abort, exit, quick_exit или что-то подобное).

Смысла этого я не понимал, но и как-то внимания не обращал. Почему-то недавно это меня заинтересовало по-настоящему, я даже написал знаменитой «Алёне Си++», с которой как-то пересекался, так как работал с её мужем, подумал, что она может следить и за Си, раз пишет на Си++. Вот что она ответила:
Я 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.
В общем, примерно понятно, хотя, на мой взгляд, всё равно выглядит как микрооптимизация.
29 января 2014 18:24

zg (zg.livejournal.com)
29 января 2014, 18:53

некоторые странные люди собирают свои проекты с -Wall -Wextra -Werror. при этом какой-нибудь код:
int foo()
{
  if(a) return b;
  else halt();
}
не соберётся. и нужно либо ставить фиктивный return в конце, либо объявлять halt с атрибутом noreturn. второй метод по мне выглядит изящней.

Евгений Степанищев (bolknote.ru)
29 января 2014, 19:04, ответ предназначен zg (zg.livejournal.com):

__Noreturn, вроде, warning даёт. А на него далеко не все внимание обращают или отключают их вовсе.

masterspammer (masterspammer.livejournal.com)
30 января 2014, 04:24

А -Werror делает из них ошибки - что и требовалось.

zg (zg.livejournal.com)
30 января 2014, 09:45, ответ предназначен Евгений Степанищев (bolknote.ru):

__Noreturn, вроде, warning даёт
нет:
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 non-void function [-Werror=return-type]
 }
 ^
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"

Евгений Степанищев (bolknote.ru)
30 января 2014, 09:54, ответ предназначен zg (zg.livejournal.com):

это нестандартный noreturn, а я про стандартный _Noreturn

Евгений Степанищев (bolknote.ru)
30 января 2014, 09:58, ответ предназначен zg (zg.livejournal.com):

Вот с дефольтными ключами:
a.c: In function 'halt':
a.c:2:5: warning: function declared 'noreturn' has a 'return' statement [enabled by default]
a.c:2:5: warning: 'noreturn' function does return [enabled by default]

zg (zg.livejournal.com)
30 января 2014, 10:18, ответ предназначен Евгений Степанищев (bolknote.ru):

Вот с дефольтными ключами:
а зачем вы halt объявили как noreturn, а в теле функции написали return?

Евгений Степанищев (bolknote.ru)
30 января 2014, 11:40, ответ предназначен zg (zg.livejournal.com):

Чтобы показать варнинг о котором речь идёт.

zg (zg.livejournal.com)
30 января 2014, 14:26, ответ предназначен Евгений Степанищев (bolknote.ru):

так если неправильно _Noreturn пользоваться, конечно варнинг будет.

Евгений Степанищев (bolknote.ru)
30 января 2014, 15:39, ответ предназначен zg (zg.livejournal.com):

Почему неправильно-то? Смысл его ещё и в том, как мне видится, чтобы показывать программисту где он ошибся — поставил return в функции, откуда не должно быть возврата.

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)