I have the following warning :
cast between incompatible function types from ‘int (*)(pile *)’ {aka ‘int (*)(struct pile *)’} to ‘void (*)(void *)’ [-Wcast-function-type]
I don't have any idea of how I can fix this warning.
Structure
typedef struct conteneur_sommets {
void *donnees;
int (*est_vide)(void *);
void (*ajouter)(void *, int);
void (*supprimer)(void *);
int (*choisir)(void *);
void (*detruire)(void *);
} conteneur_sommets;
associated function
conteneur_sommets *cs_creer_pile(int n)
{
conteneur_sommets cs = {.donnees = pile_creer(n),
.est_vide = (int (*)(void *)) pile_est_vide,
.ajouter = (void (*)(void *, int)) pile_empiler,
.supprimer = (void (*)(void *)) pile_depiler, <- warning cast
.choisir = (int (*)(void *)) pile_sommet,
.detruire = (void (*)(void *)) pile_detruire};
return cs_creer(&cs);
}
void cs_supprimer(conteneur_sommets *cs)
{
cs->supprimer(cs->donnees);
}
While suppressing the warning completely can sometimes be usefull, it is better in general to fix the issue at the code level.
The issue here is that your declarations are wrong which is reason the warning is triggered in the first place.
First avoid to combine the definition of a struct/union and the declaration of the typedef
alias. It is better to separate them, this way you can, if necessary separate declaration and definition.
typedef struct conteneur_sommets conteneur_sommets;
This creates the alias conteneur_sommets
to the opaque structure struct conteneur_sommets
. This is also called a forward declaration. The forward declaration is generally put in the header file.
Now we can define the structure
struct conteneur_sommets {
void *donnees;
int (*est_vide)(conteneur_sommets *);
void (*ajouter)(conteneur_sommets *, int);
void (*supprimer)(conteneur_sommets *);
int (*choisir)(conteneur_sommets *);
void (*detruire)(conteneur_sommets *);
};
This way you don't need to cast the function pointer and conserve type checks if it is of the right signature.
conteneur_sommets cs = {.donnees = pile_creer(n),
.supprimer = pile_depiler};
Secondly A thing that is seldom realized by C programmers is that one can define typedef aliases of function prototypes, not function pointers but directly of prototypes. This can sometime really make the code much more readable even if quite unusual. Let me give you an example with your code:
typedef int est_vide_fn (conteneur_sommets *);
typedef void ajouter_fn (conteneur_sommets *, int);
typedef void supprimer_fn(conteneur_sommets *);
typedef int choisir_fn (conteneur_sommets *);
typedef void detruire_fn (conteneur_sommets *);
this declares five function prototype type definitions.
the structure can now be declared as
struct conteneur_sommets {
void *donnees;
est_vide_fn *est_vide;
ajouter_fn *ajouter;
supprimer_fn *supprimer;
choisir_fn *choisir;
detruire_fn *detruire;
};
Your cs_supprimer
functions prototype can be declared by
supprimer_fn cs_supprimer;
and its implementation is defined as before
void cs_supprimer(conteneur_sommets *cs)
{
cs->supprimer(cs->donnees);
}