Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Débuter
Débuter Forum d'entraide pour débuter en langage C. Avant de poster -> FAQ C
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 19/11/2012, 13h46   #1
RasWisdom
Invité de passage
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 7
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2012
Messages : 7
Points : 0
Points : 0
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.
RasWisdom est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 13h51   #2
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 175
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 175
Points : 2 476
Points : 2 476
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.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 14h08   #3
RasWisdom
Invité de passage
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 7
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2012
Messages : 7
Points : 0
Points : 0
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.
RasWisdom est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 14h27   #4
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 175
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 175
Points : 2 476
Points : 2 476
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.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2012, 19h11   #5
Sve@r
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 495
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
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 : 3 495
Points : 6 601
Points : 6 601
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
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/11/2012, 11h27   #6
RasWisdom
Invité de passage
 
Homme
Étudiant
Inscription : octobre 2012
Messages : 7
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2012
Messages : 7
Points : 0
Points : 0
Je vous remercie.
RasWisdom est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 05h53.


 
 
 
 
Partenaires

Hébergement Web