Bonjour les développeurs,

Soit le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
#include <iostream>
 
class movable
{
	public:
		movable(int){}
 
		movable(const movable&) = delete;
 
		movable(movable&&)
		{
			std::cout << "move\n";
		}
 
		const movable&
		operator=(const movable&) = delete;
 
		const movable&
		operator=(movable&&) = delete;
};
 
movable
f()
{
	return movable(0);
}
 
int
main()
{
	std::cout << "test1:\n";
	movable o1 = f();
 
	std::cout << "test2:\n";
	movable o2(f());
 
	std::cout << "test3:\n";
	movable o3(std::move(f()));
 
	return 0;
}
On a une classe non copiable mais movable et une fonction qui renvoie un objet de cette classe. Dans le main(), j'effectue trois appels à cette fonction, en effectuant respectivement une assignation par copie, une construction par copie et une construction par mouvement.

Sachant que j'ai désactivé la construction par copie et l'opérateur d'assignation, je m'attends à ce que le compilateur refuse les tests 1 et 2. Seulement non, aucun problème de compilation.
Étant donné que j'ai la sortie suivante, j'imagine que c'est la NRVO qui permet ce comportement :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
test1:
test2:
test3:
move
Si je désactive la NRVO (-fno-elide-constructors), des déplacements sont effectués dans tous les cas :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
test1:
move
move
test2:
move
move
test3:
move
move
On a donc un code qui compile seulement dans le cas où le compilateur supporte la NRVO.
C'est pas un peu discutable comme comportement ? À moins que cette optimisation ait été prise en compte dans le nouveau standard ?

J'hésite à remonter ce comportement comme un bug. Vous en pensez quoi ?


Voici le Makefile pour ceux qui veulent tester (GCC 4.4 requis) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
test: main.cpp 
	g++-4.4 -o test main.cpp -W -Wall -ansi -pedantic -std=c++0x -fno-elide-constructors