Je dispose d'un programme composé de deux fichiers source (farm.c, init.c) et de deux fichiers d'en-tête correspondants (farm.h, init.h) Les deux fichiers source contiennent des gardes d'en-tête et chacun requiert des fonctions/variables de l'autre.
init.h:
#ifndef INIT_H
#define INIT_H
#include
#include
#include"farm.h"
#define PIG_SOUND "oink"
#define CALF_SOUND "baa"
enum types {PIG, CALF};
typedef struct resources {
size_t pork;
size_t veal;
size_t lamb;
size_t milk;
size_t eggs;
} resources;
typedef struct animal {
size_t legs;
char* sound;
int efficiency;
void (*exclaim)(struct animal*);
void (*work)(struct animal*, struct resources*);
} animal;
/* J'ai essayé différentes façons de déclarer des structs en plus du
typedef comme ceci */
//animal stock;
//animal farm;
void make_pig(struct animal* a, int perf);
void make_calf(struct animal* a, int perf);
#endif
farm.h:
#ifndef FARM_H
#define FARM_H
#include
#include
#include
#include
#include"init.h"
/* GCC ne reconnait pas le typedef ou l'identificateur de la struct
jusqu'à ce que ces déclarations avancées aient été faites en
plus du fichier d'en-tête init.h inclus */
//typedef struct animal animal;
//typedef struct resources resources;
void exclaim(animal* b);
void work(struct animal* b, struct resources* s);
#endif
init.c:
#include"init.h"
void make_pig(animal* a, int perf) {
a->legs = 4;
a->sound = PIG_SOUND;
a->efficiency = perf;
a->exclaim = exclaim;
a->work = work;
}
void make_calf(animal* a, int perf) {
a->legs = 4;
a->sound = CALF_SOUND;
a->efficiency = perf;
a->exclaim = exclaim;
a->work = work;
}
farm.c:
#include"farm.h"
int main() {
return 0;
}
void exclaim(animal* a) {
for (int i = 0; i < 3; i++) {
printf("%s ", a->sound);
}
printf("\n");
}
void work(animal* a, struct resources* r) {
if (!strcmp(a->sound, PIG_SOUND)) {
r->pork += a->efficiency;
}
if (!strcmp(a->sound, CALF_SOUND)) {
r->veal += a->efficiency;
}
}
Utiliser les deux types de noms (c'est-à-dire, struct ani
et animal
) fonctionne normalement très bien sur mon système Linux avec la norme C99. Cependant, lorsque j'utilise struct ani
au lieu de animal
ici, je reçois les avertissements ci-dessous pour chaque instance d'utilisation du type pour struct ani
et struct resources
.
lib/farm.h:10:21: warning: ‘struct ani’ declared inside parameter list will not be visible outside of this definition or declaration
10 | void exclaim(struct ani* a);
| ^~~
lib/farm.h:11:33: warning: ‘struct resources’ declared inside parameter list will not be visible outside of this definition or declaration
11 | void work(struct ani* a, struct resources* r);
Et 10 avertissements au total pour chaque utilisation de pointeurs de fonctions de la forme :
src/init.c:17:16: warning: assignment to ‘void (*)(struct ani *)’ from incompatible pointer type ‘void (*)(struct ani *)’ [-Wincompatible-pointer-types]
17 | a->exclaim = exclaim;
| ^
src/init.c:18:13: warning: assignment to ‘void (*)(struct ani *, struct resources *)’ from incompatible pointer type ‘void (*)(struct ani *, struct resources *)’ [-Wincompatible-pointer-types]
18 | a->work = work;
Est-ce que quelqu'un pourrait expliquer pourquoi ce comportement se produit et comment je peux éviter les problèmes ? En général, il me faut un temps incommensurable pour résoudre ces erreurs et je ne comprends pas vraiment quelle est mon erreur au départ.