11 votes

Est-il possible qu'un programme compilé ne contienne pas de classe modèle instanciée ?

Considérez ce code :

template <typename T>
class A {
    T x;
    // A bunch of functions
};

std::size_t s = sizeof(A<double>);

Supposons que le sizeof est le seul endroit où une instanciation de l'opérateur A<double> est nécessaire. Est-il possible que le programme compilé ne pas contiennent du code pertinent pour A<double> (par exemple A<double>::~A() ) ?

12voto

Oliv Points 7148

La classe sera instanciée, mais le compilateur ne doit instancier aucune définition de fonction membre, [temp.inst]/1 :

[...] la spécialisation du modèle de classe est implicitement instancié lorsque la spécialisation est référencée dans un contexte qui nécessite un type d'objet complètement défini [...]

[temp.inst]/2 :

L'instanciation implicite de la spécialisation d'un modèle de classe entraîne l'utilisation de la fonction instanciation implicite des déclarations, mais pas des définitions arguments par défaut, ou spécificateurs noexcept des fonctions membres de la classe , [...]

2voto

user0042 Points 7066

Est-il possible que le programme compilé ne contienne pas le code pertinent pour A<double> (par exemple A<double>::~A() ) ?

Bien sûr que c'est possible.

std::size_t s = sizeof(A<double>);

est juste une opération de compilation, et n'a pas besoin d'une instance d'exécution de A<double> Il n'y a donc pas besoin de constructeurs, de destructeurs ou autres. code correspondant .


Même s'il y avait des instanciations explicites du code de la fonction modèle comme suit

 if(sizeof(A<double>) <= 4) {
      A<double> a; // Instantiation of constructor and destructor
      a.x = 3.5;
 }

le compilateur est autorisé à optimiser ce code.

0voto

SoronelHaetir Points 7859

Oui, sizeof() n'a pas besoin des fonctions membres et donc elles peuvent très bien ne pas être générées. Tout ce dont sizeof a besoin, ce sont les membres de données.

0voto

J'ai construit ce code :

#include <cstddef>

template <typename T>
class A {
    T x;
    // A bunch of functions
};

int main(const int argc, const char* argv[])
{
    std::size_t s = sizeof(A<double>);
}

Et en lançant objdump j'obtiens cette sortie :

$ objdump -t a.out 

a.out:  file format Mach-O 64-bit x86-64

SYMBOL TABLE:
0000000100000000 g     F __TEXT,__text  __mh_execute_header
0000000100000f90 g     F __TEXT,__text  _main
0000000000000000         *UND*  dyld_stub_binder

Où l'on peut voir qu'aucun symbole associé au constructeur/destructeur n'a été généré.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X