Search code examples
c++cgccclanglanguage-lawyer

Is it legal to return an expression of type void?


This compiles without any warnings.

Is this legal in C and C++ or does it just work in gcc and clang?

If it is legal, is it some new thing after C99?

void f(){}

void f2(){
    return f();
}

Update

as "Rad Lexus" suggested I tried this:

$ 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)

Update

Someone asked how this construction is helping. Well is more or less syntactic sugar. Here is one good example:

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");
}

Solution

  • C11, 6.8.6.4 "The return statement":

    A return statement with an expression shall not appear in a function whose return type is void.

    No, you may not use an expression, even if it is of void type.

    From the foreword of the same document:

    Major changes in the second edition included:

    [...]

    • return without expression not permitted in function that returns a value (and vice versa)

    So this was a change from C89 -> C99 (the second edition of the language standard), and has been that way ever since.


    C++14, 6.6.3 "The return statement":

    A return statement with an expression of non-void type can be used only in functions returning a value [...] A return statement with an expression of type void can be used only in functions with a return type of cv void; the expression is evaluated just before the function returns to its caller.

    Yes, you may use an expression if it is of void type (that's been valid since C++98).