Look at the following code:
struct node
{
node();
//node(const node&); //#1
//node(node&&); //#2
virtual //#3
~node ();
node*
volatile //#4
next;
};
int main()
{
node m(node()); //#5
node n=node(); //#6
}
When compiled with gcc-4.6.1 it produces the following error:
g++ -g --std=c++0x -c -o node.o node.cc
node.cc: In constructor node::node(node&&):
node.cc:3:8: error: expression node::next has side-effects
node.cc: In function int main():
node.cc:18:14: note: synthesized method node::node(node&&) first required here
As I understand the compiler fails to create default move or copy constructor on line #6, if I uncomment either line #1 or #2 it compiles fine, that is clear. The code compiles fine without c++0x option, so the error is related to default move constructor.
However, what in the node class prevents default move constructor to be created? If I comment any of the lines #3 or #4 (i.e. make the destructor non-virtual or make data member non-volatile) it compiles again, so is it the combination of these two makes it not to compile?
Another puzzle, line #5 does not cause an compilation error, what is different from line #6? Is it all specific for gcc? or gcc-4.6.1?
That's why your #3 is breaking the synthesis.
In addition, it's far from clear that volatile types (including your
node* volatile
) are trivially copyable; it could be concluded that it is implementation-defined whether they are or not and, in your case, it seems that they are not.At the very least, GCC made it stop working quite deliberately in v4.7, with a proposal to backport into v4.6.1 that I can only presume went ahead...
So, given the following:
... that's why your #4 is breaking the synthesis too, independently of #3.
As for #5, that's not actually a declaration of a
node
at all, but a declaration for a function calledm
— that's why it's not reproducing the symptoms related to construction of anode
(this is known as the Most Vexing Parse).