2012-01-26 15 views
5

que he enfrentado la siguiente muestra:múltiples valores de retorno en función

#include <stdio.h> 

// test multiple return                                        
int foo() 
{ 
    return 1,2,3,4,5,6; 
} 

// main entry point                                         
int main(int argc, char* argv[]) 
{ 
    printf("foo returns: %d\n", foo()); 
    return 0; 
} 

compilarlo, a continuación, ejecute:

gcc main.cpp -o main 
./main 

Los resultados me están confundiendo:

foo returns: 6 

La pregunta es: ¿por qué no hay error de tiempo de compilación?

Respuesta

10

Puesto que está utilizando el comma operator: la expresión a,b donde a y b son arbitrarias (generalmente lado con efecto) sub-expresiones intentar: evaluar el lado izquierdo a y descartar su resultado (por lo a está a sólo evaluaron para la cara -efectos), luego evalúa b y dale como resultado.

No puede devolver varias cosas desde una función C. Deberías devolver, p. un agregado (generalmente un struct) o un puntero dinámicamente asignado en el montón.

En cuanto a la pregunta, ¿por qué el compilador no dice nada? Porque no lo preguntaste. Usted realmente debe compilar con gcc -Wall (para el código C) o g++ -Wall (por código C++), y luego se obtiene advertencias:

egor7.c: In function ‘foo’: 
egor7.c:6:13: warning: left-hand operand of comma expression has no effect [-Wunused-value] 
egor7.c:6:15: warning: left-hand operand of comma expression has no effect [-Wunused-value] 
egor7.c:6:17: warning: left-hand operand of comma expression has no effect [-Wunused-value] 
egor7.c:6:19: warning: left-hand operand of comma expression has no effect [-Wunused-value] 
egor7.c:6:21: warning: left-hand operand of comma expression has no effect [-Wunused-value] 
11

En este contexto:

return 1,2,3,4,5,6; 

es en realidad el comma operator. Evalúa todo entre las comas en orden (de izquierda a derecha) y devuelve el último.

Es por eso que devuelve e imprime 6. Así que sí, es un código válido. Es por eso que no hay error de compilación. (Aunque la parte 1,2,3,4,5 no hace nada en este caso)

En C y C++, no puede devolver varios valores. Tendría que usar una estructura o una clase para hacer eso.

4

En caso de duda, utilice Clang:

$ clang++ -Weverything test.cpp 
test.cpp:4:5: warning: no previous prototype for function 'foo' [-Wmissing-prototypes] 
int foo() 
    ^
test.cpp:6:10: warning: expression result unused [-Wunused-value] 
    return 1,2,3,4,5,6; 
     ^
test.cpp:6:12: warning: expression result unused [-Wunused-value] 
    return 1,2,3,4,5,6; 
     ^
test.cpp:6:14: warning: expression result unused [-Wunused-value] 
    return 1,2,3,4,5,6; 
      ^
test.cpp:6:16: warning: expression result unused [-Wunused-value] 
    return 1,2,3,4,5,6; 
      ^
test.cpp:6:18: warning: expression result unused [-Wunused-value] 
    return 1,2,3,4,5,6; 
       ^
6 warnings generated. 

Como su nombre indica , -Weverything activa cada advertencia disponible. De esta manera no tiene que recordar los grupos en los que se encuentran.

En cuanto a las explicaciones: consulte la respuesta de Mysticial sobre el operador de coma y sus efectos de secuencia. Una ocurrencia útil de este operador es:

std::list<Item> list = /**/; 
assert(list.size() >= 10); 

auto it = list.begin(); 
for (int i = 0; i < 10; ++i, ++it) { 
    std::cout << "Item " << i << ": " << *it << "\n"; 
} 

Nota cómo la tercera cláusula del bucle for utiliza el operador de coma para hacer dos operaciones en una sola sentencia.

Por supuesto, tal sintaxis es en su mayoría anecdótica, por lo que las personas se sorprenden regularmente ...

Cuestiones relacionadas