摆脱由 typedef 引起的 "Incompatible pointer" 警告

Get rid of "Incompatible pointer" warning caused by typedef

关于编译器警告,我真的很迂腐。他们帮助我调试了很多问题,所以我尝试摆脱所有问题。

我有 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

有什么方法可以让编译器满意而无需禁用此类警告?非常感谢。

编辑: 这里是警告:

note: expected ‘Base * {aka struct sBase *}’ but argument is of type ‘ChildA * {aka struct sChildA }’ void do_something(LitBase base);

您收到警告是因为 ChildA*Base* 不兼容。它们显然是不同的结构类型。并且由于它们不兼容(在此上下文中意味着相同),编译器无法在它们之间进行隐式转换。这不是一些烦人的"false positive",而是一个不容忽视的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。如果您不是语言律师,请使用第一个示例:)