Mentre il porting del codice C++ da Microsoft Visual Studio per gcc, mi sono imbattuto in uno strano bug, che alla fine ho riassunta in questo modo:distruttore di un argomento di una funzione viene chiamata in modo diverso in GCC e MSVC
#include <iostream>
using namespace std;
class Foo {
public:
int data;
Foo(int i) : data(i)
{
cout << "Foo constructed with " << i << endl;
}
Foo(const Foo& f) : data(f.data)
{
cout << "copy ctor " << endl;
}
Foo(const Foo&& f) : data(f.data)
{
cout << "move ctor" << endl;
}
~Foo()
{
cout << "Foo destructed with " << data << endl;
}
};
int Bar(Foo f)
{
cout << "f.data = " << f.data << endl;
return f.data * 2;
}
int main()
{
Foo f1(10);
Foo f2(Bar(std::move(f1)));
}
Se I compilare ed eseguire il codice precedente con Microsoft Visual Studio 2015 Community, ottengo il seguente output:
Foo constructed with 10
move ctor
f.data = 10
Foo destructed with 10
Foo constructed with 20
Foo destructed with 20
Foo destructed with 10
Tuttavia, se compilare ed eseguire il codice con gcc 6.1.1 e --std = C++ 14 , Ottengo questo risultato:
Foo constructed with 10
move ctor
f.data = 10
Foo constructed with 20
Foo destructed with 10
Foo destructed with 20
Foo destructed with 10
gcc chiama il distruttore del f
, l'argomento di Bar()
, dopo Bar()
rendimenti, mentre msvc chiama il distruttore (apparentemente) prima che ritorni, o almeno prima il costruttore di f2
. Quando si suppone che lo f
venga distrutto, secondo lo standard C++?
'f', essendo un argomento con nome di' Bar() ', non è un temporaneo. In realtà, non vedo alcun temporaneo. Gli altri due 'Foo's sono chiamati f1 e f2. Non sono sicuro se c'è una domanda reale qui. – MSalters
Probabilmente sono confuso su cosa sia un temporaneo. La mia domanda è quando l'argomento 'f' di' Bar() 'dovrebbe essere distrutto, e quale implementazione, msvc o gcc, è corretta? –
@MSalters Non vedo come questo sia un duplicato di quella domanda. Riguarda l'ordine di costruzione/distruzione in 'f (a, b, c)' ma questa domanda non chiama mai una funzione con più di 1 argomento –