c - 摆脱由 typedef 引起的“不兼容指针”警告
问题描述
当谈到编译器警告时,我真的很迂腐。它们帮助我调试了很多问题,所以我尝试摆脱所有这些问题。
我有 2 个子结构,我们称它们ChildA
为ChildB
基础结构Base
。
// predefines.h
typedef struct sBase Base;
typedef struct sChildA ChildA;
typedef struct sChildB ChildB;
// base.h
typedef struct sBase {
// Base fields
} Base;
// child_a.h
typedef struct sChildA {
Base* base;
// other things
} ChildA;
// child_b.h
typedef struct sChildB {
Base* base;
// other things
} ChildB;
应该没问题吧?它可以工作,除了它在我的代码周围产生这么多警告,其他警告,我只是无法在我的 IDE 中注意到它们,因为我只看到了这么多黄色。
我有很多功能,例如:
void do_something(Base* base) {
// Code code code
}
do_something(instance_of_child_a); // Warning here
有没有办法让编译器开心而不禁用这种类型的警告?谢谢一堆。
编辑:这是警告:
注意:预期 'Base * {aka struct sBase *}' 但参数的类型是 'ChildA * {aka struct sChildA }' void do_something(LitBase base);
解决方案
您收到警告ChildA*
是因为与Base*
. 它们显然是不同的结构类型。而且由于它们不兼容(在这种情况下意味着相同),编译器不能在它们之间隐式转换。这不是一些令人讨厌的“误报”,而是不应忽视的 C 语言违规。许多编译器会给出错误并拒绝生成二进制文件。
.base
您必须使用显式强制转换或简单地手动传递成员。
显式转换的另一种替代方法是包装宏:
void base_do_something (Base* base);
#define do_something(x) \
base_do_something ( \
_Generic( (x), ChildA*: &(x)->base, ChildB*: &(x)->base ) \
)
或同等学历:
#define do_something(x) \
base_do_something ( \
_Generic( (x), ChildA*: (Base*)(x), ChildB*: (Base*)(x) ) \
)
正如后一个示例看起来很可疑,它实际上是根据 C17 6.7.2.1 §15 有效的。而且它不违反严格的别名,因为ChildA
etc 是包含Base
在其成员之间的聚合。如果您不是语言律师,请使用第一个示例 :)
推荐阅读
- sql - 选择 DB2 中数组中的子字符串
- typescript - Typescript - 为什么我不能使用回调中的键来引用对象
- php - SuiteCRM 中如何为一个模块创建多个表?
- azure - 如何使用 Azure JavaScript SDK 访问 blob 元数据?
- json - Oracle 11g 解码 JSON blob
- server - 403 禁止:在 wowza 上使用扳手模块播放视频时不接受会话
- php - laravel 中的新项目给路线带来了问题
- android - 分享图片缩略图和标题中的文字,如 Instagram 分享到 WhatsApp Android
- php - 如何使用 Eloquent 模型获取多个表列名
- python - 重新格式化相同的字符串不起作用。我怎样才能做到这一点?