2011-01-27 18 views
10

Cuando me encontré con este programa:C++ volver valor sin instrucción de retorno

#include <iostream> 

int sqr(int&); 

int main() 
{ 
    int a=5; 
    std::cout<<"Square of (5) is: "<< sqr(a) <<std::endl; 
    std::cout<<"After pass, (a) is: "<< a <<std::endl; 
    return 0; 
} 

int sqr(int &x) 
{ 
    x= x*x; 
} 

me dieron el siguiente resultado:

Square of (5) is: 2280716 
After pass, (a) is: 25 

¿Cuál es 2280716? Y, ¿cómo puedo obtener un valor devuelto a sqr(a) mientras que no hay una declaración return en la función int sqr(int &x)?

Gracias.

+6

WTF? ¿Por qué querrías escribir tal código? Claramente, sqr es una función matemática y no tiene sentido usar el parámetro como entrada-salida. –

+0

@Ilya Kogan. Simplemente probando cómo pasar por referencia funciona – Simplicity

Respuesta

28

Estrictamente, esto causa comportamiento indefinido. En la práctica, dado que sqr tiene el tipo de retorno int, siempre devolverá algo, incluso si no está presente ninguna declaración return. Ese algo puede ser cualquier valor de int.

Agregue una instrucción return y active las advertencias en su compilador (g++ -Wall, por ejemplo).

int sqr(int &x) 
{ 
    return x = x*x; 
} 
+5

+1 para '-Wall'. (Ahora, si agrega '-Werror' ... no, no puedo votar dos veces, maldición. :-)) –

+2

Es un poco menos simple, no devuelve nada en una función con un tipo de devolución que no sea 'void' provoca un comportamiento indefinido, no solo el retorno de un valor indefinido. La diferencia es que al afirmar que devolverá un valor indefinido significa que simplemente ignorando ese valor todo estará bien, pero no es así. El programa podría fallar, corromper la pila ... –

+2

@David solo para aclarar el bit de comportamiento indefinido y asegurarse de que entiendo el problema por completo; si, por ejemplo, nuestro valor de retorno fuera un unique_ptr , sin una instrucción return, la función devolvería basura en lugar de una T *, que luego sería interpretada por la persona que llama como un único_ptr válido, e incluso si ignorara es decir, el destructor de finge unique_ptr bloqueará tu programa (con suerte) al intentar eliminar su punta. – enobayram

7

Esa es una basura que dependerá de un puñado de factores. Probablemente ese es el valor almacenado en la memoria donde la función pondría el resultado si tuviera una declaración return. Esa memoria se deja al descubierto y luego la lee la persona que llama.

No lo piense demasiado, solo agregue una declaración return.

3

Usted está tratando de imprimir el valor de retorno de SQR (int & x), que es el valor de la basura en este caso. Pero no devuelve el X * X correcto. tratar de volver válida X * X desde SQE

int sqr(int &x) { x= x*x; return x;}

4

Su función sqr() no tiene ninguna instrucción de retorno. La función tiene un comportamiento indefinido con respecto al valor de retorno. Su primer resultado muestra este valor de retorno.

Sin embargo, el compilador debería mostrar un diagnóstico.

intente esto:

int sqr(int x) 
{ 
    return x*x; 
} 
+0

'g ++' no muestra ninguna advertencia a menos que se especifique '-W'. –

+0

@larsmans. ¿Cuál es la sintaxis de usar '-W'? 'g ++ .....' Gracias – Simplicity

+0

'g ++ -Wall' para las advertencias predeterminadas. Consulte el manual de advertencias específicas. –

1

Si una función no se declara void entonces MUST tiene una sentencia return diciendo lo que debería ser el valor al volver a la persona que llama. Si no lo hace y simplemente la función finaliza sin devolver un valor, el resultado de llamar a esta función es "Undefined Behavior", lo que significa que su programa podría hacer cualquier cosa (incluso bloquear o eliminar todo lo que está en su disco duro).

Normalmente, si el valor es solo un int simple obtendrás números funky, pero en casos más complejos puede ser una fuente de grandes problemas. Simplemente no hagas eso.

Los compiladores normalmente le informarán que olvidó una declaración de devolución si se le indicó correctamente hacerlo (es decir, habilitando el nivel máximo de advertencia). Puede omitir el retorno de un valor solo para casos en los que la función realmente no retorna (es decir, arroja una excepción o bucles para siempre).

1

Necesitas hacer una elección entre:

1) Pase por referencia/valor y volver un INT.

2) Pasando por referencia AND return void.

Esta elección depende del propósito de su función.

Si desea una función que le de el cuadrado de un número, use la primera. Si desea una función que toma una variable y la reemplaza por su cuadrado, use la segunda.

Así que o bien:

int sqr(int& x) 
{ 
    return x*x; 
} 

O

void sqr(int& x) 
{ 
    x= x*x; 
} 
Cuestiones relacionadas