2010-11-18 9 views
4

Je regarde un morceau de code qui crée des variables de classe globales. Les constructeurs de ces classes appelle une table de symboles singleton et ajoute les pointeurs ce dedans ..C++ Les variables de classe globales ne sont pas créées

Dans un fichier Keywords.cpp

class A : class KeyWord 
{ 
    A() { add(); } 
} A def; 

même pour des mots-clés B, C etc

void KeyWord::add() 
{ 
CSymbolCtrl& c = CSymbolCtrl::GetInstance(); 
c.addToTable(this); 
} 

Ces unités de traduction sont compilées pour former une bibliothèque. Quand je « dumpbin » la bibliothèque, je vois les initialiseurs dynamiques pour ADEF, BDéf etc.

Non dans l'exe, quand je l'appelle l'instance CSymbolCtrl, je ne ai pas trouvé l'ADEF, BDéf .. stockées dans sa carte. Quand je mets un point d'arrêt dans add(), il ne se fait pas toucher. Est-il possible que l'éditeur de liens ignore ADef, BDef car ils ne sont référencés nulle part?

}

+1

Pourriez-vous utiliser un exemple de code plausiblement compilable? –

Répondre

3

De docs standard 1.9 L'exécution du programme,

4) Cette disposition est parfois appelée « comme si » la règle, parce qu'une implémentation est libre de ne tenir compte d'aucune exigence de la présente Norme internationale tant que le résultat est comme si l'exigence avait été respectée, dans la mesure où cela peut être déterminé à partir du comportement observable du programme. Par exemple, une implémentation réelle n'a pas besoin d'évaluer une partie d'une expression si elle peut déduire que sa valeur n'est pas utilisée et qu'aucun effet secondaire affectant le comportement observable du programme n'est produit.

Donc, il pourrait, oui.

1

La réponse courte est oui. Une façon assez commune pour forcer l'inscription est de faire quelque chose comme:

static bool foo = register_type(); 
+0

Existe-t-il un moyen de forcer les linkers à ne pas ignorer ces variables? – excray

+3

@ user97642: dans l'unité de transfert correspondante, ajoutez simplement une fonction. appelle cette fonction. Cela peut sembler magique, mais la norme exige que les variables statiques soient initialisées avant cet appel, de sorte qu'il introduit une dépendance. acclamations et hth., –

+0

@Alf P. Steinbach, Est-ce qu'un usage vide comme 'def;' quelque part ne suffit pas? Ou faut-il appeler une fonction? – liaK

1

Ce n'est pas trop clair à partir de votre question, mais êtes-vous réellement y compris les fichiers objets compilés dans votre lien ou non? Juste mettre un fichier dans une bibliothèque ne le fait pas être inclus dans le programme final. Par définition, un fichier d'une bibliothèque sera uniquement inclus dans l'exécutable s'il résout un symbole externe non résolu. Si vous voulez un fichier objet à faire partie de l' exécutable final, et il ne contient aucune globals qui résoudre un externe non défini, vous avez plusieurs choix:

- Lien le fichier objet directement, plutôt que de le mettre dans une bibliothèque. (C'est la manière «standard» ou «canonique» de de le faire.)

- Utilisez une DLL. Malgré le nom, les DLL ne sont pas des bibliothèques, mais des fichiers objets , et sont liés de manière tout ou rien.

- Créer un symbole global fictif et le référencer quelque part. (Cela peut souvent être automatisé, et pourrait être la solution préférée si vous livrez une bibliothèque en tant que fournisseur tiers .

+0

Salut James! :-) –