J'essaie de compiler un programme qui est divisé en 3 modules, correspondant à 3 fichiers sources: a.c
, b.c
et z.c
. z.c
contient la fonction main()
, qui appelle les fonctions dans a.c
et b.c
. De plus, une fonction dans a.c
appelle une fonction dans b.c
et vice-versa. Enfin, il existe une variable globale count
utilisée par les trois modules et définie dans un fichier d’en-tête séparé, global.h
.
Le code des fichiers source est le suivant:
a.c
#include "global.h"
#include "b.h"
#include "a.h"
int functAb() {
functB();
functA();
return 0;
}
int functA() {
count++;
printf("A:%d\n", count);
return 0;
}
b.c
#include "global.h"
#include "a.h"
#include "b.h"
int functBa() {
functA();
functB();
return 0;
}
int functB() {
count++;
printf("B:%d\n", count);
return 0;
}
z.c
#include "a.h"
#include "b.h"
#include "global.h"
int main() {
count = 0;
functAb();
functBa();
return 0;
}
Les fichiers d'en-tête:
a.h
#ifndef A_H
#define A_H
#include <stdio.h>
int functA();
int functAb();
#endif
b.h
#ifndef B_H
#define B_H
#include <stdio.h>
int functB();
int functBa();
#endif
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
extern int count;
#endif
Et, enfin, la makefile
qui reproduit mon erreur:
CC = gcc
CFLAGS = -O3 -march=native -Wall -Wno-unused-result
z: a.o b.o z.o global.h
$(CC) -o z a.o b.o z.o $(CFLAGS)
a.o: a.c b.h global.h
$(CC) -c a.c $(CFLAGS)
b.o: b.c a.h global.h
$(CC) -c b.c $(CFLAGS)
z.o: z.c a.h global.h
$(CC) -c z.c $(CFLAGS)
Avec cela, je peux compiler les objets a.o
, b.o
et z.o
très bien, mais lors de la liaison avec make z
, je reçois undefined reference to 'count'
dans chacun d'eux:
z.o: In function `main':
z.c:(.text.startup+0x8): undefined reference to `count'
a.o: In function `functAb':
a.c:(.text+0xd): undefined reference to `count'
a.c:(.text+0x22): undefined reference to `count'
a.o: In function `functA':
a.c:(.text+0x46): undefined reference to `count'
a.c:(.text+0x5b): undefined reference to `count'
b.o:b.c:(.text+0xd): more undefined references to `count' follow
collect2: ld returned 1 exit status
J'ai réussi à reproduire l'erreur dans mon code réel dans cet exemple minimal. Je suppose donc qu'il existe un problème de dépendance entre modules, mais je ne le vois pas. Est-ce que quelqu'un peut-il me montrer la bonne direction?
Changez votre z.c
en
#include "a.h"
#include "b.h"
#include "global.h"
int count; /* Definition here */
int main() {
count = 0;
functAb();
functBa();
return 0;
}
À partir de global.h
, tous vos fichiers héritent de la déclaration de la variable count
mais la definition est manquante dans tous les fichiers.
Vous devez ajouter la définition à l'un des fichiers en tant que int count = some_value;
Vous avez déclaré compte, pas défini il.
extern
est une partie de la déclaration, pas une définition.
Pour être explicite, extern
est un spécificateur de classe de stockage utilisé lors de la déclaration.
Vous devez définir int count
quelque part dans vos fichiers source.
Vous devez ajouter int count;
à votre fichier zc . En raison de la déclaration d'une variable dans le fichier d'en-tête en tant que extern
indique au compilateur que la variable sera déclarée dans un autre fichier, mais que la variable n'est pas encore déclarée et qu'elle sera résolue b linker.
Ensuite, vous devez déclarer la variable quelque part.