c - 在函数结构上静默 WCast-function-type
问题描述
我有以下警告:
cast between incompatible function types from ‘int (*)(pile *)’ {aka ‘int (*)(struct pile *)’} to ‘void (*)(void *)’ [-Wcast-function-type]
我不知道如何解决此警告。
结构
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;
关联功能
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);
}
解决方案
虽然完全抑制警告有时会很有用,但通常最好在代码级别解决问题。这里的问题是您的声明是错误的,这是首先触发警告的原因。首先避免将结构/联合的定义和typedef
别名的声明结合起来。最好将它们分开,这样您可以在必要时分开声明和定义。
typedef struct conteneur_sommets conteneur_sommets;
conteneur_sommets
这将创建不透明结构的别名struct conteneur_sommets
。这也称为前向声明。前向声明一般放在头文件中。
现在我们可以定义结构
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 *);
};
这样,您就不需要转换函数指针并保存类型检查是否具有正确的签名。
conteneur_sommets cs = {.donnees = pile_creer(n),
.supprimer = pile_depiler};
其次,C 程序员很少意识到的一件事是,可以定义函数原型的 typedef 别名,而不是函数指针,而是直接定义原型。即使非常不寻常,有时这确实可以使代码更具可读性。让我用你的代码举一个例子:
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 声明了五个函数原型类型定义。
该结构现在可以声明为
struct conteneur_sommets {
void *donnees;
est_vide_fn *est_vide;
ajouter_fn *ajouter;
supprimer_fn *supprimer;
choisir_fn *choisir;
detruire_fn *detruire;
};
您的cs_supprimer
函数原型可以通过以下方式声明
supprimer_fn cs_supprimer;
其实现定义如前
void cs_supprimer(conteneur_sommets *cs)
{
cs->supprimer(cs->donnees);
}
推荐阅读
- html - 在不同浏览器中显示字体
- java - java 1.7 中的哪个特性为 1.8 中的 lambda 表达式铺平了道路?
- azure - 估算 Azure 搜索成本
- c# - 没有从身份服务器获取用户“电子邮件”作为声明(来自 jwt 令牌)
- python - 如何使用 ElementTree 从 XML 元素构造字典?
- python-3.x - 将字符串附加到所有 python 日志 aws lambda
- node.js - 在 Angular 6 聊天应用程序中集成表情符号
- ios - 在 swift 项目中使用 Mojento rest api 的过程
- jquery - 获取在 jquery else if 循环中选择的值
- ruby-on-rails - rails prawn 中的阿拉伯语单词显示相反的顺序