Возвращает тип void в C и c++


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

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

если это законно, это какая-то новая вещь после C99?

void f(){

}

void f2(){
    return f();
}

обновление

как" рад Лексус " предложил я попробовал это:

$ 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 %sn", 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");
}
5 62

5 ответов:

C11, 6.8.6.4 " The return утверждение":

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

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

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

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

[...]

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

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


C++14, 6.6.3 " The return утверждение":

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

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

этот код разрешен в C++ но не допускаются в C

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

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


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

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

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

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

и 6.8.6.4 возврат

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

(даже если выражение void)

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

void f() 
{
    return void();
}

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

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

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

6.8.6.4 оператор return

ограничения

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

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

так, запрещается в с.


вы должны использовать -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();

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

C11 6.8.6.4: The return сообщении

ограничения

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

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