Возвращать тип void в C и С++

Это компиляция без каких-либо предупреждений.

Является ли это законным в C и С++ или он просто работает в gcc и clang?

Если это законно, это что-то новое после C99?

void f(){

}

void f2(){
    return f();
}

Обновление

как "Rad Lexus" предложил я попробовал это:

$ gcc -Wall -Wpedantic -c x.c 
x.c: In function ‘f2’:
x.c:7:9: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic]
  return f();

$ clang -Wall -Wpedantic -c x.c 
x.c:7:2: warning: void function 'f2' should not return void expression [-Wpedantic]
        return f();
        ^      ~~~~~
1 warning generated.

$ gcc -Wall -Wpedantic -c x.cc
(no errors)

$ clang -Wall -Wpedantic -c x.cc
(no errors)

Обновление

Кто-то спросил, как эта конструкция помогает. Ну есть более-менее синтаксический сахар. Вот один хороший пример:

void error_report(const char *s){
    printf("Error %s\n", s);
    exit(0);
}

void process(){
   if (step1() == 0)
      return error_report("Step 1");

   switch(step2()){
   case 0: return error_report("Step 2 - No Memory");
   case 1: return error_report("Step 2 - Internal Error");
   }

   printf("Processing Done!\n");
}

Ответ 1

C11, 6.8.6.4 "Оператор return":

Оператор

A return с выражением не должен появляться в функции, тип возврата которой void.

Нет, вы не можете использовать выражение, даже если оно имеет тип void.

Из предисловия того же документа:

Основные изменения во втором издании включали:

[...]

  • return без выражения, не разрешенного в функции, которая возвращает значение (и наоборот)

Итак, это было изменение от C89 → C99 (второе издание языкового стандарта) и так было с тех пор.


С++ 14, 6.6.3 "Оператор return":

Оператор return с выражением не-void-типа может использоваться только в функциях, возвращающих значение [...] Оператор return с выражением типа void может использоваться только в функциях с возвращаемым типом cv недействительным; выражение оценивается непосредственно перед тем, как функция вернется к вызывающему.

Да, вы можете использовать выражение, если оно имеет тип void (который был действителен с С++ 98).

Ответ 2

Этот код разрешен в C++, но не разрешен в C

От Оператор возврата @cppreference

В функции, возвращающей void, оператор return с выражением может если тип выражения недействителен.


OTOH в спецификации C11 проекта n1570:

Основные изменения во втором издании включали:

return без выражения, не разрешенного в функции, которая возвращает значение (и наоборот)

(return с выражением, не разрешенным в функции, которая возвращает void)

и 6.8.6.4 return

Оператор return с выражением не должен появляться в функции чей тип возврата недействителен. Оператор return без выражения должен появляться только в функции, тип возврата которой недействителен.

(даже если выражение оценивается как void)

Ответ 3

С++ позволяет что-то вроде этого:

void f() 
{
    return void();
}

Пока C не делает. Вот почему предупреждение выдается, если вы скомпилируете его ISO C, а не ISO С++. Это формально описывается как:

Оператор return с выражением типа void может использоваться только в функции с возвращаемым типом cv void

Ответ 4

ISO/IEC 9899: 201x. В проекте Комитета говорится следующее:

6.8.6.4 Оператор return

Ограничения

  • Оператор
  • return с выражением не должен появляться в функции, тип возврата которой void.

    Оператор

    A return без выражения должен появляться только в функция, тип возврата которой void.

Таким образом, это запрещено в C.


Вам нужно использовать переключатель -pedantic на gcc, чтобы жаловаться на стандартные нарушения:

test.c: In function ‘f2’:
test.c:6:12: warning: ISO C forbids ‘return’ with expression, in function returning void 
            [-Wpedantic]
     return f();

Ответ 5

Стандарт C не поддерживает эту конструкцию:

C11 6.8.6.4: Оператор return

Ограничения

1 Оператор return с выражением не должен появляться в функции, тип возврата которой void. Оператор return без выражения должен появляться только в функции, тип возврата которой void.

Никаких специальных положений для специального случая в вопросе не добавляется. Некоторые компиляторы C поддерживают это как расширение (gcc does, если не указано, что он соответствует одному из стандартов C), но C11 и предыдущие версии считают это нарушением ограничения.