web-dev-qa-db-fra.com

Référence non définie à la variable globale lors de la liaison

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?

14
freieschaf

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;

15
Mohit Jain

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.

6
Sourav Ghosh

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. 

1
LPs