2011-08-30 2 views
6

GCC insère une déclaration - peu importe comment j'essaye de l'empêcher. J'ai essayéComment empêcher GCC d'entrer en ligne

  • -fno-inline
  • -O0
  • __attribute__ ((noinline))
  • dummy asm("")

Pas de succès! Voici le code:

#include<iostream> 

using namespace std; 

struct A { 
    A() {cout << "A::A()" <<endl; } 
    A(const A& a) {cout << "A::A(copy)" <<endl; } 
    A& operator=(const A& a) {cout << "A::=()" <<endl; return *this;} 
}; 

A __attribute__ ((noinline)) func() 
{ 
    cout << "func()" << endl; 
    A loc; 
    asm(""); 
    return loc; 
} 

int main() { 
    A a = func(); 
} 

La sortie malheureuse de ce (g ++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2) est

func() 
A::A() 

Qu'est-il arrivé à la déclaration A a = func() ??

La raison de cette expérience est que je voudrais savoir ce qui se passe lorsque l'exécution vient à cette déclaration (parce que je dois contrôler la façon dont cela est fait):

A a = func(); 

Je lis que le constructeur de copie est appelée quand on fait

A a = b; 

(dans ce cas, le constructeur de copie est appelée Mais pas dans le cas a a = func();.) la fonction est inline à la place. I BESOIN contrôle sur cette instruction depuis mon "struct A" dans la vie réelle contient des données allouées dynamiquement qui doit être pris en charge.

Est-ce que je manque quelque chose d'évident ici?!

+2

Essayez '-fno-elide-constructors'. (Et notez que vous avez déclaré vos constructeurs en ligne en les définissant à l'intérieur de la définition de classe.) –

+1

Est-ce vraiment le cas? Cela me ressemble à RVO. –

+0

Merci pour la réponse! En effet, il n'est pas en ligne. C'est l'optimisation. Avec cela, je vais voir si ma vraie vie se structurer au travail. (Pour l'instant ce n'est pas le cas). Une question: Peut-on désactiver cette possibilité d'optimisation (-fno-elide-constructors) changer le comportement du programme (disons si le constructeur de la copie contient du code vital) à l'exception de la vitesse? – ritter

Répondre

15

Non, cela n'a rien à voir avec la fonction en question. L'incorporation de la fonction ne modifierait pas le comportement observable.

Il s'agit d'une optimisation appelée élision de copie qui permet au compilateur d'éviter une copie en construisant la valeur de retour directement à la destination. Vous pouvez le désactiver avec le drapeau g ++ -fno-elide-constructors.

Dans tous les cas, les données allouées dynamiquement ne devraient pas poser de problème. En supposant un constructeur de copie saine, la seule différence que vous verrez sera probablement une meilleure performance.

5

Si struct A contient des données allouées dynamiquement, il est de votre responsabilité de gérer cette mémoire dans le destructeur/constructeur approprié. De nombreuses classes gèrent les données allouées dynamiquement et fonctionnent parfaitement avec les copies ellibles. RVO et NRVO sont des optimisations importantes.

Questions connexes