【问题标题】:Get rid of "Incompatible pointer" warning caused by typedef摆脱由 typedef 引起的“不兼容指针”警告
【发布时间】:2018-12-14 09:53:53
【问题描述】:

当谈到编译器警告时,我真的很迂腐。它们帮助我调试了很多问题,所以我尝试摆脱所有这些问题。

我有 2 个子结构,我们称它们为 ChildAChildB 以及一个基本结构 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);

【问题讨论】:

  • 警告在哪里?您是否尝试在 C 中建立“is-a”关系?
  • @babon 添加了警告。而且我并不是想建立一种关系。如果代码不知道它是 Child 实例,则代码不会使用 Child 方法。真正的代码库处理与内存相关的事情,子类使用内存管理来满足他们的需要。
  • do_something(&instance_of_child_a.base); 或使用 void* 并强制转换 void do_something(void *x) { struct sBase *base = x; /* ... */ }
  • ChildA 和 Base 是独立的类型。仅当 ChildA 和 ChildB 派生自 Base 时,您的方法才有效。
  • @egordorichev:错误不是因为typedef引起的。

标签: c gcc compilation compiler-warnings


【解决方案1】:

您收到警告是因为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 等是其成员中包含Base 的聚合。如果您不是语言律师,请使用第一个示例 :)

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多