Researching the consequences of misusing the statement return
in functions void
and non- void
in the C standard I realized that it does not specify what happens when a non- function usesvoid
an return
empty statement or a function void
uses a return
non-empty statement:
int devolver_entero() { return; } // no-void usa una return vacio
What I have been able to find in the standard is the following (translations are mine):
6.8.6.4 The return statement
restrictions
- A statement
return
with an expression must not appear in a function whose return type isvoid
. A statementreturn
without an expression must appear only in functions whose return type isvoid
.
The above standard quote states what should be done with statements return
for return and non-return functions, but elsewhere in the standard it states what happens when the constraints are not followed:
6.9.1 Function definitions
- If the function terminator is reached
}
and the value of the function call is used by the caller, the behavior is undefined.
The above quote from the standard indicates that undefined behavior is incurred if the return value of a function that has reached the closing brace is used }
, so the following example has undefined behavior:
int comportamiento_indefinido(int x) { if (x) return x; }
printf("%d", comportamiento_indefinido(1)); // Correcto
printf("%d", comportamiento_indefinido(0)); // Comportamiento indefinido
In the call comportamiento_indefinido(1)
the function returns 1
through the statement return
under the conditional if (x)
; in the call comportamiento_indefinido(0)
the condition if (x)
is not met and the function ends when the closing brace is reached }
, using the return of the call comportamiento_indefinido(0)
is undefined behavior (but using the return of is not comportamiento_indefinido(1)
). But what happens in this case?
int comportamiento_indefinido(int x) { if (x) return; } // return vacio
printf("%d", comportamiento_indefinido(1)); // Comportamiento indefinido?
printf("%d", comportamiento_indefinido(0)); // Comportamiento indefinido
In the previous example, the call comportamiento_indefinido(1)
does not comply with what is indicated in §6.9.1/12
to achieve undefined behavior, since the function ends without reaching the closing brace }
and does not return any value either.
What part of the C standard takes this into account?
1 Or at least I couldn't find it.
I find the question very interesting and relevant. For example, one does not always have access to correct a code, but it would be interesting to understand what it does. For example, knowing if it is a security flaw.
It seems to me that it can be understood that both cases are equivalent. Actually, being a "
no debe
" it doesn't have to compile if it's strictly C99, right? Because otherwise it should say "no debería
". Since the original standard (in English) says:And the same standard says (bold mine):
That is, if it says nothing about the behavior, then it is undefined .
What will happen most of the time? I imagine that to the compiler it is equivalent, because a
return
no expression compiles toret
(or equivalent to) on most platforms, as does putting none. While with argument, it becomes moving to a register or pushing on the stack the result of the expression, and then returning. For example, areturn 8;
can be amov ax,8
or apush 8
before theret
. If none is specifiedreturn
in C, the compiler must still include aret
in the assembler, whether or not the function has a type, as if it had been madereturn;
. Do you understand what I say?EDITED : I remove reference to another RFC and considerations about de facto standards, finding that the same standard defines it.
(In Spanish) In other words, if a restriction of the standard, of those indicated by shall (= must) or shall not (= must not) is not fulfilled by a program, said program contains undefined behavior.
And as @ESL quote:
(In Spanish) That is, if a function
void
tries to return something (return expr;
), or if a function with a type other thanvoid
tries to return nothing (return;
), the behavior is undefined ( undefined behavior ).En tu caso, dado que tu sentencia
return
aparece sin valor en una función que requiere un valor de retorno, es comportamiento indefinido de acuerdo al punto 4.2.Conversely, this would also be undefined behavior:
These definitions are taken from: