Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 6 sur 6
  1. #1
    Invité de passage
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2012
    Messages : 10
    Points : 3
    Points
    3

    Par défaut probleme inclusions/definitions multiples

    Bonjour , je suis en train de faire un programme de gestion de processus.Cependant j'ai un petit problème avec l'inclusion de variables globales situées dans un fichier .h .Pour y remédier j'ai essayé avec le mot clé "extern" mais le problème persiste . Pourriez-vous donc m'éclairer svp?
    les erreurs en question:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    gcc tp3_main.o tp3_aff.o -o tp3_main
    tp3_aff.o: In function `verifaff':
    tp3_aff.c:(.text+0x7): undefined reference to `str1'
    tp3_aff.c:(.text+0x1c): undefined reference to `str2'
    tp3_aff.c:(.text+0x31): undefined reference to `str3'
    tp3_aff.c:(.text+0x46): undefined reference to `str4'
    tp3_aff.c:(.text+0x5b): undefined reference to `str5'
    tp3_aff.c:(.text+0x70): undefined reference to `str6'
    tp3_aff.c:(.text+0x85): undefined reference to `str7'
    tp3_aff.c:(.text+0x9a): undefined reference to `str8'
    le fichier auxquelles elles font réferences :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //str.h
    #ifndef STR_H
    #define STR_H
     
    extern char *str1;
    extern char *str2;
    extern char *str3;
    extern char *str4;
    extern char *str5;
    extern char *str6;
    extern char *str7;
    extern char *str8;
     
    #endif
    le fichier main.c(je n'ai mis que le code qui intervient dans l'erreur)
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    //main.c
    #include"tp3_str.h"
    #include"tp3_aff.h"
    #include <stdlib.h>
    #include <stdio.h>
     
     
    int main(int argc,char *argv[])
    {
    	char *str1=" _____                                                              |";
    	char *str2="|  __ \\                                                             |";
    	char *str3="| |__) |  _ __    ___     ___    ___   ___   ___   _   _   ___      |";
    	char *str4="|  ___/  |  __|  / _ \\   / __|  / _ \\ / __| / __| | | | | / __|     |";
    	char *str5="| |      | |    | (_) | | (__  |  __/ \\__ \\ \\__ \\ | |_| | \\__ \\     |";
    	char *str6="| |      | |    | (_) | | (__  |  __/ \\__ \\ \\__ \\ | |_| | \\__ \\     |";
    	char *str7="|_|      |_|     \\___/   \\___|  \\___| |___/ |___/  \\__,_| |___/     |";
    	char *str8="                                                                    |";
    }
    et enfin l'autre fichier de fonctions:
    Code :
    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
    //aff.c
    #include"tp3_str.h"
    #include"tp3_aff.h"
     
     
    void verifaff()
    {
    	printf("%s \n",str1);
    	printf("%s \n",str2);
    	printf("%s \n",str3);
    	printf("%s \n",str4);
    	printf("%s \n",str5);
    	printf("%s \n",str6);
    	printf("%s \n",str7);
    	printf("%s \n",str8);
    }
     
    void affprocess1()
    {
    	printf(" %s ",str1);
    	/*//printf("Père: %d ,Fils: %d [0]\n",getpid());*/
    	printf("%s \n",str2);
    	printf("%s \n",str3);
    	printf("%s \n",str4);
    	printf("%s \n",str5);
    	printf("%s \n",str6);
    	printf("%s \n",str7);
    	printf("%s \n",str8);
    }
    void affprocessn()
    {
    	printf(" %s ",str1);
    	/*printf("Père: %d ,Fils: %d [0]\n",getpid(),fork());*/
    	printf("%s \n",str2);
    	printf("%s \n",str3);
    	printf("%s \n",str4);
    	printf("%s \n",str5);
    	printf("%s \n",str6);
    	printf("%s \n",str7);
    	printf("%s \n",str8);
    }
    voila , votre aide me serait d'un grand secours car après avoir essayé différentes méthodes ces erreurs d'inclusions et de définitions persistent.
    En vous remerciant d'avance.

  2. #2
    Expert Confirmé Sénior
    Homme Profil pro Pierre
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    1 967
    Détails du profil
    Informations personnelles :
    Nom : Homme Pierre
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 1 967
    Points : 4 146
    Points
    4 146

    Par défaut

    extern signifie en gros "déclaration non définissante".

    Il faut quand même définir la variable quelque part.
    La variable doit être définie une et une seule fois (comme une fonction...)

    En général, il suffit de définir la variable dans un fichier .c (à part ou non)

    par exemple
    [CODE truc.h]extern int truc;[/CODE]
    [CODE truc.c]int truc;[/CODE]
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • La plus sotte des questions est celle qu'on ne pose pas.

    Pour faire des graphes, essayez yEd.

  3. #3
    Invité de passage
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2012
    Messages : 10
    Points : 3
    Points
    3

    Par défaut

    D'accord , j'avais compris en grandes lignes le fonctionnement du extern , mais je croyais que dans le cas de l'utilisation de la variable dans plusieurs fichiers, on ne pouvait pas définir plusieurs fois celle-ci.
    Je te remercie.

  4. #4
    Expert Confirmé Sénior
    Homme Profil pro Pierre
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    1 967
    Détails du profil
    Informations personnelles :
    Nom : Homme Pierre
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 1 967
    Points : 4 146
    Points
    4 146

    Par défaut

    justement, on ne peut pas définir plusieurs fois la variable, mais on peut la déclarer plusieurs fois.

    Dans cet exemple, getTruc et truc sont déclarés dans les trois unités de compilations (les trois .o), mais ne sont définis que dans un seul.

    Code truc.h :
    1
    2
    extern const int truc;
    int getTruc(void);
    Code truc.c :
    1
    2
    #include "truc.h"
    const int truc = 3;
    Code machin.c :
    1
    2
    #include "truc.h"
    int getTruc(void){return truc;}
    Code main.c :
    1
    2
    3
    4
    5
    #include "truc.h"
    #include <stdio.h>
    int main(int argc, char** argv){
    printf("truc = %d (= %d)", getTruc(), truc);
    }

    Dans ton code, les variables externes ne sont pas définies du tout, d'où les "undefined reference"
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • La plus sotte des questions est celle qu'on ne pose pas.

    Pour faire des graphes, essayez yEd.

  5. #5
    Expert Confirmé Sénior
    Avatar de Sve@r
    Homme Profil pro Frédéric
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    4 422
    Détails du profil
    Informations personnelles :
    Nom : Homme Frédéric
    Âge : 46
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 4 422
    Points : 8 650
    Points
    8 650

    Par défaut

    Citation Envoyé par RasWisdom Voir le message
    D'accord , j'avais compris en grandes lignes le fonctionnement du extern , mais je croyais que dans le cas de l'utilisation de la variable dans plusieurs fichiers, on ne pouvait pas définir plusieurs fois celle-ci.
    Je te remercie.
    En fait, la compilation séparée (plusieurs fichiers compilés séparément puis liés en final) se passe en 2 phase
    1) chaque fichier est analysé au niveau sémantique. A ce niveau, le compilo a besoin de s'assurer que toutes les variables utilisées sont connues du programmeur. Mais comme une variable n'est définie qu'une fois, la solution a été de rajouter un mot clef indiquant au compilo "je connais cette variable mais je la définis ailleurs" => extern. Bien entendu il te faut avoir défini cette variable quelque part. Pour simplifier on la défini dans le source qui contient le main

    2) édition de lien entre les sources pour créer l'exécutable => l'ensemble des références à la variable est reliée à la zone mémoire représentée par la variable, zone créée lors de la définition

    Accessoirement, on peut aussi utiliser extern pour bypasser une variable locale et référencer la globale. exemple

    Code c :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int toto=100;        // Variable globale
     
    int main()
    {
        int toto=5;      // Variable locale qui prend le pas sur la globale
     
        printf("toto=%d\n", toto);        // Affiche 5
     
        {
            extern int toto;    // Référence la globale dans ce sous-bloc
     
            printf("toto=%d\n", toto);  // Affiche 100
            toto=200;
            printf("toto=%d\n", toto);  // Affiche 200
        }
     
        printf("toto=%d\n", toto);        // Affiche toujours 5
    }

    Personnellement je fracasserais la tronche d'un développeur qui me fait ça mais juste pour dire que c'est quand-même possible...
    Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
    Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
    Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
    Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
    Dr. Adrian Rogers (1931-2005)

  6. #6
    Invité de passage
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2012
    Messages : 10
    Points : 3
    Points
    3

    Par défaut

    Je vous remercie.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •