2011-11-28 10 views
8
int& foo() { 
    printf("Foo\n"); 
    static int a; 
    return a; 
} 

int bar() { 
    printf("Bar\n"); 
    return 1; 
} 

void main() { 
    foo() = bar(); 
} 

No estoy seguro de cuál se debe evaluar primero.C++ orden de evaluación de función en el operador de asignación

He intentado en VC que la función de barra se ejecute primero. Sin embargo, en compilador por g ++ (FreeBSD), da la función foo evaluada primero.

pregunta interesante Mucho se deriva del problema anterior, supongamos que tengo una matriz dinámica (std :: vector)

std::vector<int> vec; 

int foobar() { 
    vec.resize(vec.size() + 1); 
    return vec.size(); 
} 

void main() { 
    vec.resize(2); 
    vec[0] = foobar(); 
} 

Basado en el resultado anterior, el vc evalúa la foobar() y luego realizar el vector operador[]. No es problema en tal caso. Sin embargo, para gcc, ya que el vec [0] se está evaluando y la función foobar() puede llevar a cambiar el puntero interno de la matriz. El vec [0] puede invalidarse después de la ejecución de foobar().

¿Es decir que tenemos que separar el código de tal manera que

void main() { 
    vec.resize(2); 
    int a = foobar(); 
    vec[0] = a; 
} 
+3

+2, esa es una pregunta interesante; es algo que nunca he considerado antes. Obviamente estás en problemas si empiezas a usar código así de todos modos :) –

+0

+1. Es realmente una pregunta interesante; más que eso, la pregunta se hace muy bien. Una pregunta bien escrita. – Nawaz

+1

Me encontré con un ejemplo interesante de esto hoy: 'auto_ptr p (new int); smart_map m; m [1] = p.release(); 'Si supone que' smart_map :: operator [] 'podría arrojar, podría tener un caso donde' auto_ptr' libera su propiedad pero el mapa nunca asume la propiedad, en el caso donde se evalúa el RHS antes del LHS. (Supongamos que 'smart_map' es como un 'mapa' de STL, excepto que elimina el valor del puntero de cada par clave/valor en la destrucción.) – mrkj

Respuesta

8

Orden de evaluación sería no especificado en ese caso. No te escribir dicho código

ejemplo similar here

0

Orden de evaluación de una expresión es comportamiento no especificado.
Depende del compilador cuyo orden elija evaluar.

Debe abstenerse de escribir códigos shuch.
Aunque si no hay ningún efecto secundario, entonces el orden no debería importar.

Si las cuestiones de orden, a continuación, el código es incorrecto /No portátil/puede dar resultado diferente al otro lado de diferentes compiladores **.

5

El concepto en C++ que rige si se define el orden de evaluación se llama sequence point.

Básicamente, en un punto de secuencia, se garantiza que se hayan evaluado todas las expresiones anteriores a ese punto (con efectos secundarios observables), y que aún no se hayan evaluado expresiones posteriores a ese punto.

Aunque a algunos les pueda parecer sorprendente, el operador de asignación no es un punto de secuencia. Una lista completa de todos los puntos de secuencia se encuentra en el Wikipedia article.

+2

... _was_ llamado punto de secuencia. Desde este año, estamos usando _sequenced before_/_sequenced after_. – MSalters

+0

@MSalters: ¡Gracias por señalar eso, no estaba al tanto! –

Cuestiones relacionadas