gcc bug ?

D

-de-

Dear experts !


Consider the following code snippet :

/*================================*/
/* void.c */
void f(int i)
{
i++;
if (i!=10)
return f(i);
}

int main(void)
{
f(0);
return 0;
}
/*================================*/


gcc warns me with the following message:


-------------------------------------------
$ gcc -g -W -Wall -pedantic -o x void.c
void.c: In function "f":
void.c:5: attention : "return" with a value, in function returning void
-------------------------------------------


"return with a value" ? what a nonsense !

The function f returning no value (void), the instruction
return f();
isn't an error. It's equivalent to a return statement, apart from the
function call.

This is a compiler's bug, isn't it ?

Thanks.
 
H

Harald van Dijk

void f(int i)
{ [...]
return f(i); [...]
void.c:5: attention : "return" with a value, in function returning void

I'm assuming this is a translated error message?
This is a compiler's bug, isn't it ?

No, it isn't. Firstly, it's not a fatal error, and compilers are allowed
to give messages for any code, no matter how correct, and commonly do so
for valid but questionable code. Secondly, what you're doing is not just
poor style but is actually disallowed in C, and some other compilers will
give a hard error for it. If you want to call f(i) and then return, write
that.

void f(int i)
{
[...]
f(i);
return;
[...]
}
 
K

Keith Thompson

-de- said:
Consider the following code snippet :

/*================================*/
/* void.c */
void f(int i)
{
i++;
if (i!=10)
return f(i);
}

int main(void)
{
f(0);
return 0;
}
/*================================*/


gcc warns me with the following message:
[...]

Probably the error message should say
"return" with an expression

C99 6.8.6.4:

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.

It follows from this that the expression, if any, in a return
statement cannot be of type void.

Your code would make sense if the language permitted it (you're
returning a void expression from a void function), but it doesn't, so
you don't get to do that.

Since you're not actually returning a value, you can replace this:

if (i != 10)
return f(i);

with this:

if (i != 10) {
f(i);
return;
}

or, in this particular case, with just this:

if (i != 10)
f(i);

since you're about to fall off the end of the function anyway, so the
return statement is superfluous.
 
H

Harald van Dijk

Harald van Dijk wrote:
[snip]
Secondly, what you're doing is not just poor style but is actually
disallowed in C
[more snip]

Interesting, would you like to elaborate it?

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.

This disallows

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

because while f() can be argued not to have a value, it is still an
expression.
 
B

Ben Bacarisse

-de- said:
Consider the following code snippet :

/*================================*/
/* void.c */
void f(int i)
{
i++;
if (i!=10)
return f(i);
}

int main(void)
{
f(0);
return 0;
}
/*================================*/

gcc warns me with the following message:

void.c: In function "f":
void.c:5: attention : "return" with a value, in function returning void

"return with a value" ? what a nonsense !

The wording is not ideal, but it is not nonsense!
The function f returning no value (void), the instruction
return f();
isn't an error. It's equivalent to a return statement, apart from the
function call.

This is a compiler's bug, isn't it ?

No. A diagnostic is required since the program violates a
constraint:

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.

A better message might have been "return with an expression in a
function whose return type is void", but it is the construct that is
wrong, not the compiler.

The "obvious" way to write what you want is just:

void f(int i)
{
i++;
if (i != 10)
f(i);
}
 
S

Spiros Bousbouras

-de- said:
Consider the following code snippet :
/*================================*/
/* void.c */
void f(int i)
{
i++;
if (i!=10)
return f(i);
}
int main(void)
{
f(0);
return 0;
}
/*================================*/
gcc warns me with the following message:
-------------------------------------------
$ gcc -g -W -Wall -pedantic -o x void.c
void.c: In function "f":
void.c:5: attention : "return" with a value, in function returning void
-------------------------------------------
"return with a value" ? what a nonsense !

[...]

Probably the error message should say
"return" with an expression

C99 6.8.6.4:

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.

It follows from this that the expression, if any, in a return
statement cannot be of type void.

Your code would make sense if the language permitted it (you're
returning a void expression from a void function), but it doesn't, so
you don't get to do that.

What do "expression of type void" and "void expression"
mean ?
 
R

Robert Gamble

I was also referring to this paragraph when giving my answer.

What wasn't clear to me is "is a void expression an expression at all"?

6.5.1
"An expression is a sequence of operators and operands that specifies
computation of a value"

and

6.3.2.2.1
"(A void expression is evaluated for its side effects.)"

So, it seems to me that a void expression doesn't "specify computation
of a value", thus is not an expression.

This leads me to say that

void somefunc(void)
{
int i = 0;
return (void)i;

}

is correct.

Please correct me..

Um, let's see:

1) It's called a void *expression*.

2) The first part of section 6.3.2.2p1 (which you quoted the end of)
states:

"The (nonexistent) value of a void expression (an expression that has
type void)"
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^

3) The entire part of section 6.5p1 (which you quoted the beginning
of) states:

"An expression is a sequence of operators and operands that specifies
computation of a
value, or that designates an object or a function, or that generates
side effects, or that
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
performs a combination thereof."
 
K

Keith Thompson

Pietro Cerutti said:
Keith said:
-de- said:
Consider the following code snippet :

/*================================*/
/* void.c */
void f(int i)
{
i++;
if (i!=10)
return f(i);
}

int main(void)
{
f(0);
return 0;
}
/*================================*/


gcc warns me with the following message:
[...]
Probably the error message should say
"return" with an expression
C99 6.8.6.4:
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.

I was also referring to this paragraph when giving my answer.

What wasn't clear to me is "is a void expression an expression at all"?

6.5.1
"An expression is a sequence of operators and operands that specifies
computation of a value"

and

6.3.2.2.1
"(A void expression is evaluated for its side effects.)"

So, it seems to me that a void expression doesn't "specify computation
of a value", thus is not an expression.

This leads me to say that

void somefunc(void)
{
int i = 0;
return (void)i;
}

is correct.

Please correct me..

Ok.

The standard's definition of "expression" is not very good. (See also
previous discussions regarding the standard's definition of "lvalue".)

Taking the definition literally, an expression must include two or
more operators (since the plural is used) *and* two or more operands.
This:

42

has *no* operators and *no* operands (it might be argued that 42 is an
operand, but that doesn't affect the issue), but it's clearly an
expression.

If you look at the grammar for "expression", scattered through C99
section 6.5, it's clear that both
42
and
(void)i
are expressions.

And if ``(void)i'' weren't an expression, then the grammar for a
return statement:

return expression(opt) ;

would imply that ``return (void)i;'' is illegal anyway. (It would
also make most C programs illegal.)
 
K

Keith Thompson

Spiros Bousbouras said:
What do "expression of type void" and "void expression"
mean ?

A void expression is an expression of type void.

An expression of type void is, well, an expression whose type is void.
Examples are a call to a function that returns void, and any
expression cast to type void.
 
H

Harald van Dijk

Would you like to see my answer to Keith and try to elaborate that? ;)

You already have your answer, but here's another approach:

The syntax of the return statement is:

jump-statement:
[...]
return expression[opt] ;

This means there are two forms of the return statement. They are:

return ;
return expression ;

If f() is an expression, return f(); violates 6.8.6.4p1. If f() is not an
expression, return f(); is a syntax error. So it doesn't really matter,
either way, the compiler must complain.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top