L'exactitude du code que vous écrivez ne doit jamais dépendre d'une optimisation. Il devrait générer le résultat correct une fois exécuté sur la "machine virtuelle" C ++ utilisée dans la spécification.
Cependant, ce dont vous parlez est davantage une question d’efficacité. Votre code fonctionne mieux s'il est optimisé avec un compilateur optimisant RVO. C'est bien, pour toutes les raisons mentionnées dans les autres réponses.
Toutefois, si vous avez besoin de cette optimisation (par exemple, si le constructeur de la copie entraîne l’échec de votre code), vous êtes maintenant à la merci du compilateur.
Je pense que le meilleur exemple de cela dans ma propre pratique est l'optimisation des appels de queue:
int sillyAdd(int a, int b)
{
if (b == 0)
return a;
return sillyAdd(a + 1, b - 1);
}
C'est un exemple stupide, mais il montre un appel final, dans lequel une fonction est appelée récursivement juste à la fin d'une fonction. La machine virtuelle C ++ montrera que ce code fonctionne correctement, bien que je puisse créer un peu de confusion sur les raisons pour lesquelles je me suis ennuyé d'écrire une telle routine d'addition en premier lieu. Cependant, dans les implémentations pratiques de C ++, nous avons une pile et son espace est limité. Si elle est effectuée de manière pédagogique, cette fonction devra au moins b + 1
insérer des cadres de pile dans la pile lors de son addition. Si je veux calculer sillyAdd(5, 7)
, ce n'est pas grave. Si je veux calculer sillyAdd(0, 1000000000)
, je pourrais avoir vraiment du mal à provoquer un StackOverflow (et non le bon genre ).
Cependant, nous pouvons voir que lorsque nous atteignons la dernière ligne de retour, nous en avons vraiment fini avec tout dans le cadre de pile actuel. Nous n'avons pas vraiment besoin de le garder. L'optimisation des appels en queue vous permet de "réutiliser" le cadre de pile existant pour la fonction suivante. De cette façon, nous n’avons besoin que d’un seul cadre de pile, plutôt que b+1
. (Nous devons encore faire toutes ces additions et soustractions idiotes, mais elles ne prennent pas plus de place.) En réalité, l'optimisation convertit le code en:
int sillyAdd(int a, int b)
{
begin:
if (b == 0)
return a;
// return sillyAdd(a + 1, b - 1);
a = a + 1;
b = b - 1;
goto begin;
}
Dans certaines langues, l’optimisation de l’appel final est explicitement requise par la spécification. C ++ n'en fait pas partie. Je ne peux pas compter sur les compilateurs C ++ pour reconnaître cette opportunité d'optimisation des appels en aval, sauf si j'y vais au cas par cas. Avec ma version de Visual Studio, la version finale optimise les appels en aval, contrairement à la version de débogage (de par sa conception).
Ainsi , il serait mauvais pour moi dépends d'être en mesure de calculer sillyAdd(0, 1000000000)
.