Bonjour les développeurs,
Soit le code suivant :
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.
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; }
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 :
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 test1: test2: test3: move
On a donc un code qui compile seulement dans le cas où le compilateur supporte la NRVO.
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
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
Partager