IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Erreur d'inclusion multiple?


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Par défaut Erreur d'inclusion multiple?
    Salut,

    J'ai trois fichiers individu.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #ifndef IND
    #define IND
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>		// Pour strcpy
    #include <windows.h>	// Pour sleep
    #include <conio.h>		// Pour getch()
     
     
    	typedef struct structPersonne { 
    		char numSS[50];
    		char nom[50];
    		char prenom[50];
    	}Personne;
     
     
    	Personne monTab[4];
    	int nbPers;
     
    	char * getNumSS(Personne & P);
    	char * getNom(Personne & P);
    	char * getPrenom(Personne & P);
     
    	void setNumSS(char leNum[50], Personne & P);
    	void setNom(char * leNom, Personne & P);
    	void setPrenom(char * lePrenom , Personne & P);
     
     
    	Personne ajoutPers(char nom, char prenom, char numSS);
     
    	void suppPers(Personne & laPersonne);
    	void affPers(Personne & P);
    	void fpurge(FILE *fp);
     
    #endif
    individu.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    #include "individu.h"
     
    	// Getters
    	char * getNumSS(Personne & P){
    		return P.numSS;
    	}
     
    	char * getNom(Personne & P){
    		return P.nom;
    	}
     
    	char * getPrenom(Personne & P){
    		return P.prenom;
    	}
     
     
    	// Setters
    	void setNumSS(char leNum [50] , Personne & P){
    		strcpy(P.numSS, leNum);
    	}
     
    	void setPrenom(char * lePrenom , Personne & P){
    		strcpy(P.numSS,lePrenom);
    	}
     
    	void setNom(char * leNom , Personne & P){
    		strcpy(P.nom, leNom);
    	}
     
     
    	// Fonctions additionnelles
     
    	Personne ajoutPers(char nom, char prenom, char numSS){
    		printf("Creation d'une personne\n");
    		Personne PersonneCree;					// Personne créé
    		printf("\nSaisir Nom: ");
    		scanf("%s" , &PersonneCree.nom);
    		printf("\nSaisir Prenom: ");
    		scanf("%s" , &PersonneCree.prenom);
    		printf("\nSaisir numSS: ");
    		scanf("%s" , &PersonneCree.numSS);
     
    		return PersonneCree;					// On retourne cette personne, elle sera mise a la case nbPers
     
    	}
     
     
    	void suppPers(Personne & laPersonne){
    	// Simulation d'attente :)
    	printf("\n\nSuppresion en cours ");
    	Sleep(1000);
    	printf(" .");
    	Sleep(1000);
    	printf(" .");
    	Sleep(1000);
    	printf(" .");
    	Sleep(1000);
     
    	// On met les champ à vide
    	strcpy(laPersonne.nom, "");
    	strcpy(laPersonne.prenom, "");
    	strcpy(laPersonne.numSS, "");
    	//nbPers--;
     
    	}
     
     
    	void affPers(Personne & P){			// Consulter les données d'une personne
     
    		system("CLS");
    		printf("Nom : %s \n", P.nom);
    		printf("Prenom : %s \n", P.prenom);
    		printf("Num Secu : %s \n\n", P.numSS);
    		system("pause");
     
    	}
     
     
     
    void fpurge(FILE *fp){
    	int c;
    	while ((c = fgetc(fp)) != '\n' && c != EOF){
    	}
     
    }
    et main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    /*----------------------------------- Individu V 0.1 -----------------------------------*/
     
    #include "individu.h"
     
     
    char choix= ' ';
    int saisie = 0;
    int i;
     
    int main(){
     
    do{		// Tant que l'on choisi pas l'option 4
     
    		system("CLS");													// Clear Screen
     
    		printf("___ Chevalier 1.0 ___\n\n1. Ajouter une Personne \n2. Supprimer une personne \n3. Lister les personnes\n4. Quitter\n\n");
    		scanf("%c", &choix);
     
    		system("CLS");													// Clear Screen
     
     
    		switch (choix) {
     
    			case '1' :
     
     
    				break;
     
    			case '2' :
     
    				break;
     
    			case '3' :
     
    				system("CLS");												// Clear Screen
     
    				break;
     
    			case '4' :
     
    				break;
     
    			default: 
    				printf("\nChoix non valide !\n");
    				getch();
     
    			} // Fin du switch
     
    	fpurge(stdin); // Correction d'un bug de scanf
     
    	}while (choix != 4);	// Fin tant que
     
     
     
    	//Fin du prog
    	printf ("---------- Fin du programme ----------\n\n") ;
    	system("pause");
    	return 0;
     
     
    }
    Lors de l'edition des liens j'ai l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    1>main.obj : error LNK2005: "int nbPers" (?nbPers@@3HA) déjà défini(e) dans individu.obj
    1>main.obj : error LNK2005: "struct structPersonne * monTab" (?monTab@@3PAUstructPersonne@@A) déjà défini(e) dans individu.obj
    1>C:\Users\Keweed\Documents\Visual Studio 2008\Projects\individu\Debug\individu-bug.exe : fatal error LNK1169: un ou plusieurs symboles définis à différentes reprises ont été rencontrés
    On dirai un problème d'édition de liens du à l'inclusion multiple de individu.h, pourtant j'ai bien mis les #ifndef et #endif. Je ne comprend pas pourquoi j'ai toujours cette erreur.

    PS : je sais que le code n'est pas propre d'ailleur il n'est pas de moi mais ce que j'aimerai savoir c'est d'ou viens l'erreur.

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Tu as défini tes variables globales dans le .h au lieu de les y déclarer seulement.
    http://emmanuel-delahaye.developpez....s.htm#globales
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Par défaut
    Salut,

    Désolé pour ma réponse tardive. D'abord merci pour ta réponse. Le lien que tu m'a donné ne dit pas qu'il ne faut pas déclarer la variable global dans le header.

    Il est recommandé que la définition d'une variable globale soit faite exclusivement dans un fichier source (.c).
    Donc en théorie je ne comprend pas d'ou viens l'erreur. Le problème a été résolu mais je ne comprend pas pourquoi on ne peut pas mettre la variable global dans le header si on le protège contre les inclusions multiples. Donc si quelqu'un voit ce qui ne va pas je suis preneur. Merci.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Tu confonds déclaration et définition.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Par défaut
    Je connais très bien la différence entre déclaration et définition. Bon j'ai un début de piste. Je donne des fichiers simplifié pour mieux comprendre.

    individu.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int G_var; //variable global
    individu.cpp

    main.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "individu.h"
     
    void main()
    {
    }
    L'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    1>main.obj : error LNK2005: "int G_var" (?G_var@@3HA) déjà défini(e) dans individu.obj
    1>C:\Users\Keweed\Documents\Visual Studio 2008\Projects\Chevalier\test\Debug\test.exe : fatal error LNK1169: un ou plusieurs symboles définis à différentes reprises ont été rencontrés
    Le truc que je ne comprend vraiment pas c'est que si je renomme les fichiers cpp en c alors je n'ai plus d'erreur. Donc si quelqu'un pouvait me dire pourquoi en c++ il y a une erreur. Merci

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    individu.h

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    extern int G_var; //déclaration

    individu.cpp

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    #include "individu.h"

    main.cpp

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include "individu.h"
    
    int G_var; //définition
    
    int main()
    {
    	return 0;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Par défaut
    Médinoc ce que je cherche ce n'est pas le code propre pour définir des variables globales. Ce que j'aimerai c'est savoir ce qu'il se passe au niveau du compilateur (et de l'édition des liens) au niveau du C++. Quel est la différence pour que en C il n'y est pas d'erreur alors qu'en C++ il y a une erreur de redéfinition.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Pour moi, il devrait y avoir une erreur aussi en C.
    Tu renommes bien les deux fichiers en .c, non? Car si tu n'en renommes qu'un, il n'y aura pas de conflit à cause du Name Mangling.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Par défaut
    Je renomme bien les 2 fichiers en .c et aucune erreur lors de la compilation (individu.h, individu.c et main.c et je ne change pas le code). Je compile sous visual. Quelle est la différence entre la compilation en C et C++ pour qu'il n'y est pas d'erreur en C?

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Je viens de faire un test, et il est concluant: Apparemment en C, si la variable n'est pas initialisée, ça compte comme une déclaration, ou une histoire du genre.

    Si tu remplaces:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    int G_var; //variable global
    Par:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    int G_var = 0; //variable global
    Tu obtiens une erreur d'édition de liens même en C.

    PS: Il faudrait voir aussi comment réagit gcc...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Par défaut
    Je suis pas sur d'avoir tout compris. Ce qui est bizarre c'est que dès qu'on essaye de se servir de la variable globale (même dans le main) l'erreur se produit. Je ne sais pas à quoi cela peut bien servir puisque l'on ne peut pas utiliser la variable sans avoir une erreur. Je te remerci pour tes réponses, cela m'a bien aidé.

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Keweed Voir le message
    individu.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include "individu.h"
     
    	// Getters
    	char * getNumSS(Personne & P){
    		return P.numSS;
    	}
    Pas du C. Je déplace ?

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Keweed Voir le message
    je ne comprend pas pourquoi on ne peut pas mettre la variable global dans le header si on le protège contre les inclusions multiples. Donc si quelqu'un voit ce qui ne va pas je suis preneur. Merci.
    La protection agit contre les inclusions multiples dans la même unité de compilation.

    Je rappelle qu'une unité de compilation est traitée de manière autonome par le compilateur. Si un même objet ou fonction est défini dans 2 unités de compilation, le compilateur n'en sait rien. C'est dans la phase suivante (édition de lien) que l'éditeur de lien va chercher à regrouper les exécutables partiels générés par le compilateur en un fichier exécutable final unique. Si il y a des doublons (2 variables ou 2 fonctions avec le même nom, il signale le conflit et refuse de générer le code.

    http://emmanuel-delahaye.developpez....htm#production

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. inclusions multiples c++
    Par persam dans le forum C++
    Réponses: 2
    Dernier message: 30/11/2005, 14h09
  2. Problème d'inclusions multiples
    Par Le Furet dans le forum C
    Réponses: 2
    Dernier message: 03/10/2005, 23h59
  3. [Upload] Upload : erreur et envoi multiple
    Par linou dans le forum Langage
    Réponses: 4
    Dernier message: 07/09/2005, 09h41
  4. Réponses: 3
    Dernier message: 25/01/2005, 12h31
  5. Erreurs IIS avec Multiples Frames avec xmlrad
    Par powerlog dans le forum XMLRAD
    Réponses: 4
    Dernier message: 01/07/2003, 13h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo