Pregunta

Por favor, considere el siguiente código:

struct foo
{
    foo()
    {
        std::cout << "Constructing!" << std::endl;
    }

    foo(const foo& f)
    {
        std::cout << "Copy constructing!" << std::endl;
    }

    ~foo()
    {
        std::cout << "Destructing.." << std::endl;
    }
};

foo get()
{
    foo f;
    return f;
}

int main()
{
    const foo& f = get();
    std::cout << "before return" << std::endl;
    return 0;
}

Salida en MSVC

Constructing!
Copy constructing!
Destructing..
before return
Destructing..

Salida de GCC

Constructing!
before return
Destructing..

El resultado que viene en MSVC parece incorrecta.

Preguntas

  1. Que yo sepa, GCC produce el resultado correcto en este caso. ¿Por MSVC está dando resultados diferentes y por qué está haciendo la construcción copia?
  2. const foo& f = get() y const foo f = get() produce misma salida debido a la optimización del valor de retorno. En este caso, lo que se debe preferir forma de escribir?

Cualquier pensamiento ..

¿Fue útil?

Solución

Su construcción MSVC no tiene optimizaciones. Encenderlos, obtendrá la salida idéntica para ambos.

GCC se limita a ejecutar, por defecto, en su RVO temporal. Se trata básicamente de hacer:

const foo& f = foo();

MSVC no lo es. Se hace la foo en la función, copiarlo en el fuera de la función (ergo la llamada constructor de copia), destruyendo la foo interior, a continuación, se une la referencia.

Las dos salidas son correctos. RVO es un caso en que el estándar permite explícitamente el comportamiento observable del programa para el cambio.

Otros consejos

valor de retorno optimización, que es una especie de copiar elisión . Ambos programas son correctos; el compilador se da específicamente la opción de eliminar un temporal que sólo sirve para mover datos de un objeto permanente a otro.

La función get () es la construcción de la (Construir impresión!) Local y devolver un objeto de Foo por valor. El objeto de Foo siendo devuelto debe ser creado y se hace así a través de la construcción de copia (copia impresa construir!). Tenga en cuenta que este es el valor del objeto asignado a la foo const & F de principal.

Antes de que la asignación se lleva a cabo, sin embargo, la función debe devolver desde get () y variables locales (es decir foo f; en get ()) debe ser destruido. (Imprimir primero Destructing ..) A partir de ahí las termina el programa (es decir, regresa de principal), entonces el objeto devuelto por get () y asignado a "f" se destruye. (Imprimir segundo Destructing ...)

La razón por la que se está viendo salida diferente para los dos compiladores GCC es que está optimizando el valor de retorno para get () y es simplemente reemplazar const foo &f = get() a const foo &f = foo;

1) Esto sucede debido a diferente estrategia de optimización. Debido a que no cuenta con el operador =, MSVC código puede reestructurar a algo así como foo const & f (get ()), por tanto, la ejecución de la copia onstructor. 2) Depende de lo que quiere acheive:

const foo& f = get();
f = get(); // Incorrect, const references cannot be reassigned.
const foo g = get();
g = get(); // Correct.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top