2010-02-24 9 views

Répondre

5

Je suppose qu'ils font référence à l'optimisation de la valeur de retour mis en œuvre dans de nombreux compilateurs où le code:

CThing DoSomething(); 

se transformé en

void DoSomething(CThing& thing); 

avec chose étant déclaré sur la pile et passait pour DoSomething:

CThing thing; 
DoSomething(thing); 

qui empêche CThing d'avoir besoin d'être copié.

+0

C'est encore mieux que ça. Le compilateur est autorisé à construire un 'CThing' directement dans l'instruction de retour de' DoSomething', évitant complètement le surdébit. –

5

Souvent, cela n'arrive pas parce que cela n'est pas nécessaire. C'est ce qu'on appelle l'élision de la copie. Dans de nombreux cas, la fonction n'a pas besoin de faire des copies, donc le compilateur les optimise. Par exemple, avec la fonction suivante:

big_type foo(big_type bar) 
{ 
    return bar + 1; 
} 

big_type a = foo(b); 

obtiendrai converti en quelque chose comme:

void foo(const big_type& bar, big_type& out) 
{ 
    out = bar + 1; 
} 

big_type a; 
foo(b, a); 

La suppression de la valeur de retour est appelée la « Optimisation Valeur de retour » (de RVO), et est mis en œuvre par la plupart des compilateurs, même lorsque les optimisations sont désactivées!

+1

Ce n'est pas exactement correct. Dans votre premier extrait de code, le compilateur peut construire 'a' directement dans l'instruction' return'. Il n'a pas le temps de construire un 'big_type' par défaut comme le suggère votre second exemple de code. –

1

Le compilateur peut appeler le constructeur de copie pour la valeur de transfert ou la valeur de retour par valeur, mais il n'a pas à le faire. La norme permet de l'optimiser (en standard, elle s'appelle copy elision) et en pratique beaucoup de compilateurs le feront, même si vous n'avez pas d'optimisations activées. L'explication est assez détaillée, donc je vais vous diriger vers C++ FAQ LITE.

Version courte:

struct Foo 
{ 
    int a, b; 
    Foo(int A, int B) : a(A), b(B) {} 
}; 

Foo make_me_a_foo(int x) 
{ 
    // ...blah, blah blah... 
    return Foo(x, x+1); // (1) 
} 

Foo bar = make_me_a_foo(42); // (2) 

L'astuce est ici le compilateur est autorisé à construire bar de la ligne (2) directement en ligne (1) sans encourir de frais généraux de construction Foo temporaires objets.

Questions connexes