标题中的陈述在哪种情况下是正确的?哪个版本的C以及哪个编译器选项?
我的问题源自史蒂夫的陈述: “您现在应该注意到-因为我们的FooSubclass的第一个成员实际上是Foo结构-任何对FooSubclass的引用也是对Foo的有效引用-意味着它几乎可以在任何地方使用。”({ {3}})这是我第一次看到有人提到这种事情。以下代码会发出警告,因此我对此声明的有效性提出疑问。
#include <stdio.h>
#include <assert.h>
typedef struct Foo {
int weight;
} Foo;
Foo foo_init(int weight) {
Foo t;
t.weight = weight;
return t;
}
int foo_weight(const Foo *this) {
return this->weight;
}
typedef struct Bar {
Foo base;
int size;
} Bar;
Bar bar_init(int weight, int size) {
Bar w;
w.base = foo_init(weight);
w.size = size;
return w;
}
int bar_weight(const Bar *this) {
return foo_weight(this);
}
int bar_size(const Bar *this) {
return this->size;
}
int main (int argc, char *argv[]) {
Foo t = foo_init(22);
Bar w = bar_init(20,14);
assert(foo_weight(&t) == 22);
assert(bar_weight(&w) == 20);
assert(bar_size(&w) == 14);
return 0;
}
结果:
> gcc main.c
main.c: In function 'bar_weight':
main.c:31:20: warning: passing argument 1 of 'foo_weight' from incompatible pointer type [-Wincompatible-pointer-types]
return foo_weight(this);
^~~~
main.c:14:5: note: expected 'const Foo * {aka const struct Foo *}' but argument is of type 'const Bar * {aka const struct Bar *}'
int foo_weight(const Foo *this) {
答案 0 :(得分:2)
标题中的陈述在哪种情况下是正确的?
无条件。正确的说法是“ Bar的第一个成员是Foo结构,可以将对Bar的任何引用投射为对Foo的有效引用”。
这在6.7.2.1p15的C标准中有记录:
6.7.2.1结构和联合说明符
5指向经过适当转换的结构对象的指针指向 它的初始成员(如果该成员是位字段,则为该单元 它所在的位置),反之亦然。可能有未命名的填充 在结构对象中,而不是在结构对象的开头。
自从C的概念出现以来就是如此。