C ++ comportamiento inesperado (¿dónde están mis temporales?)

Este fue un experimento de valor r, pero mutó cuando gcc se quejó por la falta de movimiento-constructor (lo había eliminado) y no recurrió al constructor de copia (como esperaba) que luego eliminé -std = c ++ 11 desde las banderas y probé lo que ves a continuación, tiene mucha salida (inicialmente no) porque estoy tratando de averiguar por qué exactamente no funciona (sé cómo depurar pero encuentro los mensajes en la salida estándar son un buen indicador de que algo está sucediendo)

Aquí está mi código:

#include <iostream>

class Object {
public:
    Object() { id=nextId; std::cout << "Creating object: "<<id<<"\n"; nextId++; }
    Object(const Object& from) {
         id=nextId; std::cout << "Creating object: "<<id<<"\n"; nextId++;
        std::cout<<"(Object: "<<id<<" created from Object: "<<from.id<<")\n";
    }
    Object& operator=(const Object& from) {
        std::cout<<"Assigning to "<<id<<" from "<<from.id<<"\n";
        return *this;
    }
    ~Object() { std::cout<<"Deconstructing object: "<<id<<"\n";}

private:
    static int nextId;
    int id;
};

int Object::nextId = 0;

Object test();

int main(int,char**) {
    Object a;
    std::cout<<"A ought to exist\n";
    Object b(test());
    std::cout<<"B ought to exist\n";
    Object c = test();
    std::cout<<"C ought to exist\n";
    return 0;
}


Object test() {
    std::cout<<"In test\n";
    Object tmp;
    std::cout<<"Test's tmp ought to exist\n";
    return tmp;
}

Salida:

Creating object: 0
A ought to exist
In test
Creating object: 1
Test's tmp ought to exist
B ought to exist
In test
Creating object: 2
Test's tmp ought to exist
C ought to exist
Deconstructing object: 2
Deconstructing object: 1
Deconstructing object: 0

Uso deconstrucción, porque deconstrucción ya es una palabra, a veces uso destructor, nunca estoy del todo contento con la palabra, prefiero destructor como sustantivo.

Esto es lo que esperaba:

A to be constructed
tmp in test to be constructed, a temporary to be created from that 
    tmp, tmp to be destructed(?) 
that temporary to be the argument to B's copy constructor
the temporary to be destructed.
C's default constructor to be used
"" with a temporary from `test`
C's assignment operator to be used
the temporary to be destructed
c,b,a to be destructed.

Me han llamado "D-hard C" y estoy tratando de aprender a usar C ++ como algo más que "C con espacios de nombres".

Alguien podría decir "el compilador lo optimiza". Me gustaría que esa persona nunca responda una pregunta con tal respuesta ahora o nunca, las optimizaciones no deben alterar el estado del programa, debe sercomo si todo sucedió como dice la especificación, por lo que el compilador me puede poner humor al poner un mensaje en cout que incluya el número, no puede molestar ni siquiera aumentar el número, pero la salida del programa sería la misma que si lo hiciera haz todo lo que el código describe.

Entonces no son optimizaciones, ¿qué está pasando?

Respuestas a la pregunta(4)

Su respuesta a la pregunta