Question

Je lis et relis les clauses pertinentes sur ODR dans le C ++ standard, mais cette question reste encore ouverte à moi. La norme dit que la définition d'une fonction en ligne doit apparaître dans chaque unité de traduction dans lequel il est utilisé, et les définitions sont identiques dans un sens qui est décrit dans presque une page. Il dit la séquence jeton doit être le même. Est-il inclure les noms d'identificateurs locaux?

En d'autres termes Le programme suivant violez les ODR? (j'ai essayé de moi-même tester avec Visual Studio 2008 et a reçu 0 erreurs et 0 avertissements. Mais je suppose que cela ne prouve rien, parce que je puis changé l'exemple de deux définitions complètement différentes et encore eu 0 erreurs et 0 avertissements. En excuse de MSVC il convient de noter qu'aucun est formellement nécessaire de diagnostic pour les violations des ODR).

//main.cpp
inline int f(int);
int main(){
   f(3);
}
int f(int x){
   int z = x;
   return z*z;
}

//other.cpp
inline int f(int xx){
   int zz = xx;
   return zz*zz;
}
Était-ce utile?

La solution

Identifier est une sorte de jeton, chaque identifiant est un jeton séparé, donc oui, vous devez avoir le même identifiant pour respecter l'ODR. Il peut faire une différence dans un compilateur qui détectent ce (quelqu'un prêt à construire un exemple pour COME avec le modèle exporté? Il peut détecter une violation de la ODR).

Ensuite, il y a une différence entre C et C ++ ici. C n'a pas l'ODR en général et les règles de fonctionnement en ligne dans C99 (il n'y a pas de fonctions en ligne dans C90) sont tout à fait différentes de celles de C ++. En C99, votre code est correct. En fait, vous pouvez fournir une définition complètement différente. Une conséquence est que dans C (mais pas en C ++), si vous utilisez la même définition et cette définition a un membre de statique, vous avez en fait autant de variables statiques que TU en utilisant la fonction.

Autres conseils

Oui, il viole ODR. Il utilise des séquences symboliques différentes, je ne sais pas ce qui est si difficile à comprendre ici.

Vérification ODR dans toutes les unités de traduction est difficile (impossible) avec des techniques traditionnelles de compilation. La norme dit que « Aucun diagnostic nécessaire », vous obtenez juste un comportement non défini.

Vous pouvez obtenir des erreurs encore plus subtiles lorsque vous utilisez par exemple deux classes différentes définies dans les unités de traduction sans rapport, mais avec le même nom. S'il y a une table virtuelle, il peut entrer en conflit sans aucun message d'erreur (il est arrivé à mon ami). Alors toujours utiliser un namespaces anonyme pour les fonctions locales et des classes.

Identifiers sont des jetons, donc par la même séquence de jetons règle générale, le programme viole le ODR.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top