Je suis tombé sur un bug curieux aujourd'hui que j'avais en quelque sorte réussi à éviter jusqu'à maintenant.
file1.cpp: strong> p> file2.cpp: strong> p> main.cpp: strong> p> parce que Je me demande s'il y a une option de liaison ou similaire qui me permettra de produire un AVERTISSEMENT Lorsque ce type d'erreur est effectué? p> p> impression () code> a une liaison inline, cela ne produit aucune erreur de définition multiple (compilée avec
g ++ -wall file1.cpple fichier2.cppp main.cpp code>) et Le symbole dupliqué est effondré silencieusement. Le cas réel où j'ai vu cela était avec des méthodes de classe en ligne, pas des fonctions en ligne explicites, mais l'effet est identique. P>
4 Réponses :
Je vais à l'impénie Copy-coller à partir d'un fil d'email J'ai trouvé Voici sur un sujet similaire ... P>
Ce n'est pas un problème de GCC. P>
Vous n'avez pas mentionné le système d'exploitation que vous utilisez. Je suppose que c'est Gnu / linux. Sur GNU / Linux, ou tout autre système basé sur elfe, il y a un Espace de noms globaux unique des variables globales et des fonctions. Quand deux Les bibliothèques partagées utilisent le même nom de variable global, ils se réfèrent à la même variable. Ceci est une fonctionnalité. P>
Si vous voulez quelque chose de différent, examinez la visibilité des symboles et scripts de version de liaison. P> blockQuote>
Il semblerait que vous puissiez pouvoir dire à la liaison / compilateur que Symbole X devrait être unique et se plaindre si ce n'est pas le cas. P>
It n'est pas nécessaire / mandaté fort> qu'une erreur / avertissement soit généré, par la norme. Il s'agit d'une violation de C ++ 's une règle de définition em>, à cause de leur avoir Différents corps de fonction. P>
citant de:
inline externe par défaut em> p>
Le sens de "extern inline" est que Le comportement est cohérent avec la définition de GCC de Lien vague A > em> ici. P>
Merci. En regardant en arrière, j'aurais dû formuler la question mieux, mais pour clarifier - je réalise que le programme est en violation et que le comportement de la GCC est correct - je suis juste intéressé par des moyens (probablement spécifiques à une boîte à outils spécifique) de la détecter au moment de la compilation.
Les fonctions ne sont pas une liaison interne ou dans un espace de noms anonyme, ils sont donc visiblement externes avec le même nom. Ils ont des corps différents afin que vous ayez clairement violé la règle d'une définition. À ce stade, toute spéculation sur ce qui se passera n'est pas utile car votre programme est mal formé. P>
Je suppose que vous avez compilé sans optimisation et que le compilateur a généré des appels de fonction au lieu de l'affranchissement réellement, et il a choisi l'un des organes à utiliser comme fonction à appeler (laissant l'autre orpheline). Maintenant, probablement si vous avez compilé avec optimisation, votre sortie attendue serait émise, mais votre programme serait toujours incorrect. P>
Modifier pour le commentaire: Malheureusement, il n'est pas nécessaire que les compilateurs diagnostiquent des violations de la règle d'une définition (et elles ne peuvent même pas être en mesure de détecter tous les cas). Cependant, il y a quelques points que vous pouvez faire: p>
static code> ou dans un espace de noms anonyme (i préférez-vous l'espace de noms à des fins de regroupement logique, mais c'est bien). LI>
- Payer une attention particulière à
inline code> (quel que soit l'emplacement) car ils disent explicitement le compilateur que toutes les versions seront identiques (pour des méthodes non intégrées, vous aurez probablement au moins un symbole en double. erreur de la liaison). L'approche la plus sûre ici consiste ici à éviter les fonctions en ligne des espaces de noms mondiaux (ou prendre des soins particuliers dans votre nommée). De plus, vous devez être vraiment prudent que modifier #define code> s ne change pas le corps de fonction (par exemple en utilisant affirmation code> dans une fonction inline où une utilisation a ndebug code> et l'autre ne pas). LI>
- Utilisez de manière logique des classes et des espaces de noms pour casser le code et aider à prévenir plusieurs définitions du même symbole. Li>
ul>
Oui, c'était sans optimisation. J'imagine que ce serait comme vous le décrivez avec optimisation activé (au moins avec ces petites fonctions). Je réalise que le programme est mal formé et le comportement de GCC est correct - juste intéressé par les moyens de détecter / empêcher cela.
Pour créer une fonction locale à un fichier .cpp (ou .c), vous devez faire cette fonction comme Ceci est juste une hypothèse de la façon dont il a agi sur ma machine. J'ai essayé le même code sur un mac OS X Mountain Lion et j'ai eu le même résultat que vous, mais j'ai pu résoudre le problème en ajoutant * Si vous modifiez l'ordre des fichiers dans la compilation, le comportement changerait. Essayez sincèrement,
Abdulrahman Alotaibi P> statique code>. Lorsque vous avez déclaré imprimé dans deux fichiers .CPP distincts, les deux où compilé à
print_v code>, le deuxième symbole a été supprimé (ignoré) * par le compilateur. P>
statique code> aux deux fonctions. P>
g ++ file {2,1} .cppr main.cpp code> et la sortie doit être p>
print2 code> p>
print2 code> p>
Je ne pense pas que cela imprimera
print1 print1 code>. Il devrait imprimer
print2 code> aussi.