При переносе некоторого кода на С++ из Microsoft Visual Studio в gcc я столкнулся с странной ошибкой, которая в конечном итоге сводилась к следующему:
#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)));
}
Если я компилирую и запускаю вышеуказанный код с помощью сообщества Microsoft Visual Studio 2015, я получаю следующий вывод:
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
Однако, если я компилирую и запускаю код с gcc 6.1.1 и -std = С++ 14, я получаю этот вывод:
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 вызывает деструктор f
, аргумент Bar()
, после Bar()
возвращает, а msvc вызывает деструктор (по-видимому) до его возвращения или, по крайней мере, перед конструктором f2
. Когда f
предполагается разрушить, согласно стандарту С++?