c++ - una - tipos de funciones en c
Omitiendo declaraciĆ³n de retorno en C++ (3)
Aunque un compilador de C ++ no siempre puede detectar cuando una función no puede ejecutar una declaración de retorno, generalmente puede hacerlo.
En el lado positivo, al menos g ++ hace que esto sea fácil de detectar con la opción del compilador de línea de comando "-Wreturn-type". Solo necesitas recordar para habilitarlo. (También se habilita si usas "-Wall".)
Acabo de tener un comportamiento extraño de una versión de g ++ para Windows que obtuve con Strawberry Perl. Me permitió omitir una declaración de devolución.
Tengo una función miembro que devuelve una estructura que consta de dos punteros, llamada boundTag
:
struct boundTag Box::getBound(int side) {
struct boundTag retBoundTag;
retBoundTag.box = this;
switch (side)
{
// set retBoundTag.bound based on value of "side"
}
}
Esta función me dio un mal resultado y descubrí que no tenía una declaración de retorno. Tenía la intención de devolver retBoundTag
pero olvidé escribir la declaración de devolución. Una vez agregué return retBoundTag;
todo estuvo bien.
Pero yo había probado esta función y boundTag
salida de boundTag
correcta. Incluso ahora, cuando elimino la declaración de devolución, g ++ la compila sin avisar. WTF? ¿Supongo que devolver retBoundTag
?
C y C ++ no requieren que tenga una declaración de return
. Puede que no sea necesario tener uno, porque la función entra en un bucle infinito o porque lanza una excepción.
Prasoon ya citó la parte relevante de la norma:
[Sección 6.6.3 / 2]
Una declaración de retorno con una expresión solo se puede utilizar en funciones que devuelven un valor; el valor de la expresión se devuelve al llamador de la función. Si es necesario, la expresión se convierte implícitamente al tipo de retorno de la función en la que aparece. Una declaración de devolución puede implicar la construcción y copia de un objeto temporal (class.temporary). Fluir fuera del final de una función es equivalente a un retorno sin valor; esto resulta en un comportamiento indefinido en una función de retorno de valor.
Lo que significa es que no tener una declaración de retorno está bien. Pero llegar al final de la función sin regresar es un comportamiento indefinido .
El compilador no siempre puede detectar estos casos, por lo que no es necesario que se trate de un error de compilación (tendría que resolver el problema de detención para determinar si alguna vez la ejecución llega al final de la función). Es simplemente indefinido lo que debería suceder si esto ocurre. Puede parecer que funciona (debido a que la función de llamada solo mirará el valor de la basura que se encuentra en la ubicación donde se supone que debe estar el valor de retorno), puede bloquearse o hacer que los demonios salgan volando de tu nariz.
La omisión de la declaración de return
en una función non-void
[Excepto main()
] y el uso del valor devuelto en su código invoca un comportamiento indefinido .
ISO C ++ - 98 [Sección 6.6.3 / 2]
Una declaración de retorno con una expresión solo se puede utilizar en funciones que devuelven un valor; el valor de la expresión se devuelve al llamador de la función. Si es necesario, la expresión se convierte implícitamente al tipo de retorno de la función en la que aparece. Una declaración de devolución puede implicar la construcción y copia de un objeto temporal ( class.temporary ). Fluir fuera del final de una función es equivalente a un retorno sin valor; esto resulta en un comportamiento indefinido en una función de retorno de valor .
Por ejemplo
int func()
{
int a=10;
//do something with ''a''
//oops no return statement
}
int main()
{
int p=func();
//using p is dangerous now
//return statement is optional here
}
En general, g ++ da una warning: control reaches end of non-void function
. Intenta compilar con la opción -Wall
.