Omitir statement de devolución en C ++

Acabo de tener un comportamiento extraño de una versión de g ++ para Windows que obtuve con Strawberry Perl. Me permitió omitir una statement 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 resultado negativo y descubrí que no tenía statement de devolución. Tuve la intención de devolver retBoundTag pero olvidé escribir la statement de devolución. Una vez que agregué, return retBoundTag; todo estuvo bien.

Pero probé esta función y boundTag resultado correcto de boundTag . Incluso ahora, cuando elimino la statement de devolución, g ++ la comstack sin previo aviso. WTF? ¿Adivina devolver retBoundTag ?

Omitir la statement de return en una función non-void [Excepto main() ] y usar el valor devuelto en su código invoca Comportamiento no definido .

ISO C ++ – 98 [Sección 6.6.3 / 2]

Un enunciado de retorno con una expresión solo se puede usar en funciones que devuelven un valor; el valor de la expresión se devuelve a la persona que llama de la función. Si es necesario, la expresión se convierte implícitamente al tipo de devolución de la función en la que aparece. Una statement de devolución puede involucrar 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 da como resultado un comportamiento indefinido en una función que devuelve 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 . Intente comstackr con la opción -Wall .

C y C ++ no requieren que tenga una statement de return . Puede que no sea necesario tener uno, porque la función entra en un bucle infinito o porque arroja una excepción.

Prasoon ya citó la parte relevante de la norma:

[Sección 6.6.3 / 2]

Un enunciado de retorno con una expresión solo se puede usar en funciones que devuelven un valor; el valor de la expresión se devuelve a la persona que llama de la función. Si es necesario, la expresión se convierte implícitamente al tipo de devolución de la función en la que aparece. Una statement de devolución puede involucrar 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 da como resultado un comportamiento indefinido en una función que devuelve valor.

Lo que significa es que no tener una statement de devolución está bien. Pero llegar al final de la función sin regresar es un comportamiento indefinido .

El comstackdor no siempre puede detectar estos casos, por lo que no es necesario que sea un error de comstackción (tendría que resolver el problema de detención para determinar si la ejecución realmente llega al final de la función). Simplemente no está definido lo que debería suceder si esto ocurre. Puede parecer que funciona (porque la función de llamada simplemente verá el valor de basura en la ubicación donde se supone que debe estar el valor de retorno), podría colapsar o hacer que los demonios salgan volando.

Aunque un comstackdor de C ++ no siempre puede detectar cuándo una función no puede ejecutar una statement de retorno, por lo general puede hacerlo.

En el lado positivo, al menos g ++ hace que esto sea fácil de detectar con la opción del comstackdor de línea de comandos “-Wreturn-type”. Solo necesita recordar habilitarlo. (También se habilita si usa “-Wall”).