27

Consider the following snippet:

void f(void);

void g(…)
{
  …
  return f();
  …
}

Is this return f(); valid according to C11?

I am not advocating using this pattern: if it works at all, it is obviously equivalent to f(); return; (where the return; itself would be redundant if this is at the end of function g()). I am asking this question in the context of the static analysis of C programs, where the C code has already been written by someone else and the question is deciding whether or not it is valid according to the standard.

I would interpret C11 6.8.6.4:1 as meaning that it is non-standard and should be statically rejected. Is it possible to interpret it differently (I have found this pattern in actual and otherwise high-quality source code)?

Constraints

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

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • Does the compiler you are using reject the code, accept the code quietly or accept it with a warning? Was the code once ISO C? – Ray Toal Mar 19 '14 at 14:30
  • 1
    @RayToal GCC accepts the program in al-Khwārizmī's answer with `-std=c11 -Wall` without a peep, but `-pedantic` causes a diagnostic. – Pascal Cuoq Mar 19 '14 at 14:32
  • Clang warns with `-Wpedantic` as well: `void function 'f' should not return void expression [-Wpedantic]` – Carl Norum Mar 19 '14 at 14:34
  • 3
    GCC diagnosing only with `-pedantic` is a good indicator that this is a conforming extension. I assume this is for compatibility with C++, where [stmt.return]/3 says "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." – Casey Mar 19 '14 at 14:35
  • 1
    The sentence "A return statement with an expression shall not appear in a function whose return type is void" also appears in the [C89 standard](http://port70.net/~nsz/c/c89/c89-draft.html), so the fact that compilers warn rather than generate static errors here is probably just a pragmatic choice. – Ray Toal Mar 19 '14 at 14:36
  • @casey, consider writing an answer. It seems very likely that this is a construct taken over from C++. – Shahbaz Mar 19 '14 at 15:00

3 Answers3

18

Anything after return is an expression.

6.8.6:1 Jump statements

Syntax  

   ...
   return expressionopt; 

And standard says that:

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

f() is also an expression here. The compiler should raise a warning

[Warning] ISO C forbids 'return' with expression, in function returning void [-pedantic]
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    You are right: I didn't look at it this way, but the grammar in 6.8.6:1 makes it clear that `f()` should be considered as an expression: it cannot be anything else according to the grammar. – Pascal Cuoq Mar 19 '14 at 14:36
10

This clearly is a constraint violation, in particular in view of

6.3.2.2 void: The (nonexistent) value of a void expression (an expression that has type void) shall not be used in any way,

That means that the incomplete type void is a dead end that cannot be reused for any purpose whatsoever.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

It clearly states A return statement without an expression shall only appear in a function whose return type is void, try and execute this:

void g()
{
    return; // does not return any expression at all
}
void f()
{
    return g();
}


int main(void) {
    f();
    return 0;
}
Sadique
  • 22,572
  • 7
  • 65
  • 91