6
votes

Enums contradictoires

Que se passe-t-il si deux libs différents définissent la même énorme et que je dois utiliser les deux libs dans le même projet?

Enum mois {janvier = 0, février, ..., décembre}

merci.

P.s. C'est c. pas d'espaces de noms. Je ne pourrai pas les garder séparés. Besoin de solution de contournement.

Qu'est-ce que c'est le lien Enum? Interne ou externe? C libs utilisés dans le projet C ++. C ++ balise s'applique.

c c++

9 commentaires

J'espère que les deux libs utilisent des espaces de noms séparés?


Ce n'est vraiment pas différent de multiples définitions conflictuelles de types, de variables ou de fonctions.


Est-ce c ou c ++? Ils ne sont pas une langue.


Démons nasaux, évidemment.


C Code utilisé dans C ++ est dans l'espace de noms global et Enum s n'est pas vraiment interne ou externe. Ils s'appliquent si vous les déclarez. Il n'y a pas de nom à mettre dans le binaire, de sorte que cela n'a pas d'importance.


J'ai toujours supprimé la balise C ++ car même si vous l'utilisez dans un projet C ++, le code est toujours C. Dans tous les cas, la réponse C ++ serait "Utiliser des espaces de noms".


Je me rends compte que cela ne résout pas votre problème, mais vous pourriez peut-être demander aux auteurs de ces packages ce qu'ils fumaient lorsqu'ils sont venus avec ces énumes. Je ne peux pas penser à une raison viable d'entre eux d'exister au niveau source, à moins que l'intention ne soit du calendrier de Code Hard Data dans les fichiers source. En d'autres termes, à côté de cela, quelle utilisation possible pourrait janvier ou décembre avoir dans un fichier source?


@In silico. C ++ Tag s'applique. Voir la réponse de Nawaz.


@Maxpm: Le comportement est bien défini - c'est juste que si vous sautez à travers des cerceaux, vous ne recevrez même pas de compilation réussie.


5 Réponses :


12
votes

c libs utilisés dans le projet C ++. C ++ balise s'applique

Étant donné qu'elles sont utilisées dans des projets C ++, vous pouvez utiliser l'espace de noms lorsque vous y comprendrez le code C ++ comme suit: xxx


2 commentaires

@ Pic11: Je ne sais pas comment votre structure de code est. Mais une chose est sûre, chaque fois que vous ajoutez une nouvelle bibliothèque à vos projets C ++, qui provoquent des conflits de noms, vous pouvez toujours inclure la nouvelle bibliothèque dans un espace de noms différent.


J'écris C ++ API et le même énorme est déjà défini dans l'espace de noms de mon Lib. Le code d'utilisateur peut réussir la valeur ENum à mon API qui passe à son tour la même valeur à C API.



2
votes

Idéalement, les deux sont dans des espaces de noms différents.

Sinon, vous pourrez peut-être éviter les deux définitions dans une seule unité de compilation.

EDIT : D'accord, vous êtes en C, vous n'avez donc pas d'espaces de noms, et il semble que vous souhaitez référencer les deux définitions dans la même unité de compilation. Prochaines étapes:

  • ont-ils exactement la même définition?
  • Avez-vous une influence sur les noms dans l'une des bibliothèques?
  • Êtes-vous sûr de ne pas masquer les références à l'une d'elles dans une unité de compilation différente?

3 commentaires

Les définitions sont identiques.


@pic: si les définitions sont identiques, il ne devrait y avoir aucun problème.


@Oli. Oui, aucun problème tant que les définitions de deux libs ne sont pas incluses dans la même unité de traduction.



6
votes

Solution de contournement ultime Magic Magic Wizard: si des espaces de noms ne vous aident pas (pour une raison quelconque), et que vous ne pouvez absolument pas éviter, y compris les deux définitions du même fichier, utilisez une macro: xxx

Dans le fichier, n'utilisez jamais mois , uniquement file_a_montath ou file_b_month . Je ne suis pas certain des normes - exactitude de cette pratique.

Vous devrez peut-être définir tous les membres ENum de la même manière que pour prévenir les affrontements, et vous voulez probablement mettre ce mauvais piratage dans un fichier appelé fichiers_a_and_b.h . Bien sûr, dans votre cas, les définitions sont identiques, vous n'avez donc pas besoin de recourir à cela, mais je quitte cette réponse ici pour une postérité moins fortunée.


1 commentaires

Les noms constants de l'énumération identiques entraîneront des affrontements de noms même si les définitions sont identiques. Mais comme mentionné, l'application du piratage macro à chacun des noms d'ENUM fera l'affaire.



4
votes

ni le enum lui-même ni les constantes de dénombrement sont des objets, ils n'ont donc aucun lien du tout - à cet égard, ils sont comme struct étiquettes ou Typedef noms.

Cela signifie que vous avez deux travaux de contournement:

  • Assurez-vous que les en-têtes conflictuels ne sont jamais, directement ou indirectement, #include D dans la même unité de traduction ( .c fichier); ou
  • blanchissez un ou des deux en-têtes pour modifier les noms contradictoires.

    Le blanchiment d'en-tête peut être effectué soit en créant une copie privée de l'en-tête avec les noms modifiés, soit à l'aide du préprocesseur comme dans La réponse de Chris Lutz .


1 commentaires

+1. Citation: Assurez-vous que les en-têtes contradictoires ne sont jamais, directement ou indirectement, #inclus dans la même unité de traduction



0
votes

Quote: J'écris C ++ API et le même Enum est déjà défini dans l'espace de noms de mon Lib.

Donc, une de ces énumes est à l'intérieur de l'espace de noms de votre bibliothèque? Ensuite, vous ne devriez pas avoir de problème. La bibliothèque C que vous utilisez est dans l'espace de noms global, votre bibliothèque a son propre espace de noms et aussi longtemps que vous faites la bonne chose, les deux ne seront jamais collisées. Ce qui suit est parfaitement valide, je crois: xxx


0 commentaires