web-dev-qa-db-fra.com

"Plusieurs définitions de" erreur du compilateur C++

Je n'arrive pas à me débarrasser de ces erreurs de compilation apparemment aléatoires dans l'une de mes classes ..__ Je reçois environ 4 erreurs telles que:

multiple definition of `draw_line(float, float, float, float)'

et

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

qui sont marqués au milieu de la méthode.

J'obtiens aussi systématiquement multiple definition of `stack' au milieu d'une autre méthode. stack est une variable globale dans un fichier totalement différent. Ce n'est même pas mentionné dans le fichier où l'erreur me parvient.

J'ai essayé de séparer le fichier sujet aux erreurs en fichiers .h et .cpp (c'était à l'origine juste un fichier .cpp) et rien n'a changé à propos de l'erreur ...

Je n'ai pas de méthodes en double. Je n'ai qu'un seul #include de lignes.h et il y a une clause #ifndef au début. Toutes ces erreurs apparaissent dans le fichier .cpp.

Des idées ce que cela pourrait être?

Bon, j'ai le code en place:

Le fichier lines.cpp est un fichier .c converti que j'ai reçu de mon instructeur. J'ai inclus le fichier makefile au cas où, parce que j'ai toujours des problèmes avec. J'ai également noté exactement où les erreurs ont été signalées dans le fichier, mais elles semblent assez aléatoires, donc je ne sais pas si c'est particulièrement important. J'ai abandonné le fichier .h car il ne résolvait rien et ne facilitait pas la tâche. Je crois qu'il sera plus facile de trouver l'erreur sans cela.

Voici le fichier main.cpp demandé (il n'y a pas de .h).


J'ai refait le fichier lines.h en raison de et je reçois toujours le:

multiple definition of `draw_line(float, float, float, float)'

et

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

erreurs dans le fichier lines.cpp, mais l'erreur multiple definition of `stack' est maintenant à un endroit aléatoire dans le fichier ThreeD.cpp (et est marquée par un commentaire maintenant). Update: Cette erreur a été corrigée et les fichiers ont été révisés pour indiquer ceci:

Je me suis amusé à étiqueter certaines variables globales extern, mais cela ne semblait avoir aucune incidence.

14
Chad

Pourquoi incluez-vous lines.cpp dans ThreeD.cpp? C'est très inhabituel.

Votre makefile veut lines.o, vous allez donc compiler lines.cpp. Tout ce qui est défini dans lines.cpp sera dans lines.o et également dans ThreeD.o.

Il y a un commentaire intriguant dans lines.cpp:

Don't forget to put declarations in your .h files. 

Je pense que l'instructeur veut que vous divisiez lines.cpp en un .h et un .cpp.

Extrait de lines.cpp:

/* These go in your .h file or in lines.h */
/*

Line drawing header.

*/


void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
                  float *, float *);

Je soupçonne que ces deux déclarations sont la seule chose qui devrait être dans les lignes.h.

14
Thomas L Holaday

Vous êtes susceptible d'inclure les définitions de fonction dans un fichier d'en-tête. Incluez le mot clé inline pour qu’ils ne soient pas exportés par chaque fichier d’objet, ou placez-les dans leur propre fichier .cpp.

Pour votre variable globale, vous devez utiliser le mot clé extern dans votre fichier d'en-tête. Sinon, chaque fichier objet exporte sa propre variable et l'éditeur de liens se demande quel est le fichier correct à utiliser.

34
strager

S'il vous plaît envoyer des extraits de code. Peut-être définissez-vous vos méthodes à la fois dans la déclaration de classe et à l’extérieur?

class X {
    void foo();    // No definition, just declaration
    void bar() {}  // Declaration + definition
};

void X::foo() {}    // First Definition, OK
void X::bar() {}    // Already defined, ERROR
3
Ferdinand Beyer

Vérifiez inclure des gardes sur orthographe.
Vérifiez vos options de création, peut-être une personne compilée dans plusieurs fichiers objets.
Essayez d’exclure des parties de fichiers et du code jusqu’à ce que vous ne trouviez pas la cause des erreurs. 

Édité:
correction inclure les fichiers * .cpp. Ils sont devraient être liés.

3
bayda

Comme il a été dit - pas assez d’informations pour diagnostiquer correctement ici.

Mais si draw_line et autres sont définis dans un fichier d'en-tête plutôt que dans un fichier source (cpp), vous pouvez avoir des méthodes supposées être déclarées en ligne dans le fichier d'en-tête, mais qui ne le sont pas correctement. Dans ce cas, chaque fichier .cpp comprenant l'en-tête générera sa propre définition de la fonction draw_line et générera des avertissements au moment du lien.

Cela peut arriver si vous utilisez une macro INLINE #defined qui provient d'un en-tête système oublié ou supprimé, et pour quelque raison que ce soit, INLINE n'est pas prétraité.

Par exemple.:

//Lines.h

#define GCCC //Note the typo

#if defined(GCC)
#define INLINE inline
#Elif defined (MSVC)
#define INLINE __inline
#else

#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif

INLINE void draw_line(float x1, float y1, float x2, float y2)
{
   //Draw the line
}

//File1.cpp
#include "lines.h" //will define draw_line

//File2.cpp
#include "lines.h" //will also define draw_line

Et lier File1.cpp et File2.cpp générera plusieurs erreurs de déclaration

3
MrCranky
#ifndef THREED_H_
#define THREED_H_
#endif /* THREED_H_ */

supprimer ou commenter ces lignes et cela a fonctionné pour moi 

2
Gaurav Maan

Les erreurs de définition multiples sont des erreurs de l'éditeur de liens, mais sans plus d'informations, il est difficile de les diagnostiquer. Vérifier que le même fichier n'apparaît pas deux fois dans la commande de l'éditeur de liens et que vos fichiers d'en-tête ne contiennent que des déclarations, pas de définitions.

1
anon

Sans voir le code, personne ne vous aide vraiment. Le compilateur affirme clairement le contraire de vous (il est au moins une définition dupliquée).

Essayez de reproduire l'erreur avec un exemple minimum. Avez-vous essayé de compiler le code en dehors de Eclipse en ligne de commande? Avec quel résultat?

1
Konrad Rudolph

Bonjour, Ce que je vois ici que la règle de base s’applique pour ll. Je vais expliquer comment les choses fonctionnent dans ce genre d’erreurs et ce qui vient: Prenons un exemple de "Créer une variable globale"

Ne confondez pas le fichier d'en-tête, pour un fichier cpp . L'en-tête sert uniquement à permettre à plusieurs projets de fichiers d'avoir une interface Commune .__ commune avant la liaison.

1.Liste de la liste

Vous devriez donner des informations sur la variable globale dans l'en-tête:

extern int Var_Global;

  1. Élément de liste

    while keeping the Actual code in the
    cpp :
    
    int Var_Global;
    

Et assurez-vous que vous 1. incluez l'en-tête et 2. liez le code.

Liez le code une fois, et une seule fois, et il n’existe qu’une seule copie des données, Cependant, vous pouvez inclure des en-têtes toute la journée, cela indique à l’autre code que Il y aura une copie des données sur link. temps.

Je vois beaucoup de gens mettre du code dans des fichiers d'en-tête, alors que cela peut marcher dans Dans certains cas, c'est une mauvaise habitude à prendre, qui causera des problèmes plus tôt ou Plus tard.

Cordialement,

Prashanta

0