Return void type in C and C++
C++CGccClangLanguage LawyerC++ Problem Overview
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");
}
C++ Solutions
Solution 1 - C++
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).
Solution 2 - C++
This code is allowed in C++
but not allowed in C
From Return statement @ cppreference
> In a function returning void, the return statement with expression can > be used, if the expression type is void.
OTOH in C11 specs draft n1570:
Major changes in the second edition included:
> return without expression not permitted in function that returns a > value (and vice versa)
(return
with expression not permitted in function that returns a void
)
and 6.8.6.4 return
> 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.
(even if the expression evaluates to void
)
Solution 3 - C++
C++ allows something like that:
void f()
{
return void();
}
While C does not. That's why a warning is issued if you compile it a ISO C rather than ISO C++. This is formally described as:
> A return statement with an expression of type void can be used only in > functions with a return type of cv void
Solution 4 - C++
ISO/IEC 9899:201x Committee draft says the following:
> 6.8.6.4 The return statement
>
> Constraints
>
> 1. 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
.
So, it is forbidden in C.
You need to use -pedantic
switch to gcc
for it to complain about standard violations:
test.c: In function ‘f2’:
test.c:6:12: warning: ISO C forbids ‘return’ with expression, in function returning void
[-Wpedantic]
return f();
Solution 5 - C++
Standard C does not support this construction:
> C11 6.8.6.4: The return
statement
>
> Constraints
>
> 1 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
.
No special provisions are added for the special case in the question. Some C compilers do support this as an extension (gcc
does, unless instructed to conform to one of the C Standards), but C11 and previous versions consider it a constraint violation.