Utrata wartości + magiczny powrót

0

minimalny przykład:

#include <iostream>

using namespace std;

typedef __int64 int64;

class Int
{
public:
  friend ostream& operator<< (ostream& os, const Int& a);
  friend const Int& operator+ (int64 a, const Int& b);
  
  Int(const Int& a): val(a.val)  {}
  Int(int64 a): val(a)    {/*cout << "kontruktor ";*/}

private:
  int64 val;
};

ostream& operator<< (ostream& os, const Int& a) { return os << a.val; }
const Int& operator+ (int64 a, const Int& b)    { return Int(a+b.val); }

int main()
{
  Int a = 1;
  Int b = 1+a;
  cout << b;
  return 0;
}

output:
38578014732195064

po czymś takim, myślę sobie: "głupi błąd", więc dodałem prostego cout-a, w powyższym kodzie jest zakomentowany, po odkomentowaniu output:
kontruktor kontruktor 2

jak to wyjaśnić? gdzie jest ten błąd?

1
  1. Czym to kompilujesz? (bo u mnie nie występuje taki problem ;])
    2 Skompiluj do poziomu asemblera i porównaj ;]
0

opcje, o ile dobrze spisałem z Code:-O -O2 -Os -std=gnu++11

g++ --versiong++ (GCC) 4.7.0 20111224 (experimental)

jak skompilowałem teraz z linii poleceń to mi warning wyskoczył, którego Code::Blocks mi nie pokazał wcześniej:

ass.cpp: In function 'const Int& operator+(int64, const Int&)':
ass.cpp:21:69: warning: returning reference to temporary [enabled by default]

z tym assemblerem to nie jestem pewien czy to jest dobry pomysł bo mi 6k linii kodu wygenerował...

może spytam inaczej, jak taki kod powinienem prawidłowo zrobić, bo wydaje mi się, że gdzieś tu jakiś prosty błąd popełniam. Wiem, że zwracam referencję na tymczasowy obiekt, ale wydaje mi się, że ten tymczasowy obiekt przestaje istnieć w momencie przepisania. Jeśli się mylę to pewnie usunięcie const i referencji powinno pomóc..

1

No i widzisz, kompilator dał ci odpowiedź. Zwracasz referencję do obiektu tymczasowego i stąd takie jaja ;] To jest duży błąd, bo w chwili przypisania ten lokalny obiekt moze juz nie istnieć! W chwili zakończenia wywołania operator+() obiekt ginie i w trakcie wywołania operator=() / konstruktora kopiującego nie masz pewności czy można się do tego jeszcze odwoływać.

1

teraz pytanie, co mam ustawić w code blocksie żeby mi nie ukrywał tego typu warningów..?
EDIT:
myślałem, że "inhibit all warnings" oznacza co innego :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1