GCC强制转换指向不兼容类型的指针
当使用GCC编译时,我有一个可以工作的C代码,但我试图找出代码是否工作是因为纯粹的运气,还是因为GCC按照我的设计预期处理了这段代码 注意 我不是想“修复”它。我正在努力理解编译器 以下是我所拥有的: iexample.hGCC强制转换指向不兼容类型的指针,c,pointers,gcc,struct,C,Pointers,Gcc,Struct,当使用GCC编译时,我有一个可以工作的C代码,但我试图找出代码是否工作是因为纯粹的运气,还是因为GCC按照我的设计预期处理了这段代码 注意 我不是想“修复”它。我正在努力理解编译器 以下是我所拥有的: iexample.h #ifndef IEXAMPLE_H_ #define IEXAMPLE_H_ /* The interface */ struct MyIf { int (* init)(struct MyIf* obj); int (* push)(struct MyIf*
#ifndef IEXAMPLE_H_
#define IEXAMPLE_H_
/* The interface */
struct MyIf
{
int (* init)(struct MyIf* obj);
int (* push)(struct MyIf* obj, int x);
void (* sort)(struct MyIf* obj);
};
/* The object, can be in different header */
struct Obj1
{
struct MyIf myinterface;
int val1;
int val2;
};
struct Obj1* newObj1();
#endif
iexample.c
#include <stdio.h>
#include <stdlib.h>
#include "iexample.h"
/* Functions here are "equivalent" to methods on the Obj1 struct */
int Obj1_init(struct Obj1* obj)
{
printf("Obj1_init()\n");
return 0;
}
int Obj1_push(struct Obj1* obj, int x)
{
printf("Obj1_push()\n");
return 0;
}
void Obj1_sort(struct Obj1* obj)
{
printf("Obj1_sort()\n");
}
struct Obj1* newObj1()
{
struct Obj1* obj = malloc(sizeof(struct Obj1));
obj->myinterface.init = Obj1_init;
obj->myinterface.push = Obj1_push;
obj->myinterface.sort = Obj1_sort;
return obj;
}
#include "iexample.h"
int main(int argc, char* argv[])
{
struct MyIf* myIf = (struct MyIf*) newObj1();
myIf->init(myIf);
myIf->push(myIf, 3);
myIf->sort(myIf);
/* ... free, return ... */
}
当我编译时,正如我期望的那样,,我得到了在newObj1()中分配指针的结果
只要我有“struct MyIf myinterface”作为struct的第一个成员,代码就可以工作,这是设计的(我喜欢拍自己的脚)
现在,尽管我分配了不兼容的指针类型,并且C规范说行为是未定义的,但是GCC或其他编译器是否对如何处理这种情况做出了任何设计声明?我几乎可以发誓,由于struct内存是如何布局的,这应该是可行的,但我找不到证据
感谢C11标准6.7.2.1结构和联合规范: 在结构对象中,非位字段成员和 位字段所在的单元的地址增加 声明它们的顺序。指向结构的指针 对象(经过适当转换)指向其初始成员(或 如果该成员是位字段,则指向它所在的单元 ,反之亦然。其中可能有未命名的填充 结构对象,但不在其开头
所以,只要您只访问第一个结构成员,它就可以工作。然而,我相信你明白,这是一个非常糟糕的主意。如果将此代码导入C++,并使一些<代码> Obj成员虚拟化,这将立即失败。 +1给出了一个不那么琐碎的例子,说明了它是如何失败的,同时也说明了规格。我找错了地方。@M.M是这样吗?给定的引文不表明它必须按照标准以这种方式工作吗?@sepp2k不,引文只谈到结构layout@M.M它说结构的地址将始终等于第一个成员的地址,对吗?因此,当转换到成员的类型时,指向结构的有效指针也将是指向第一个成员的有效指针。sepp2k,我得出的结论是sepp2k是错误的。这个代码是正确的。搜索“面向对象的C pdf”会显示类似技术的结果。
warning: assignment from incompatible pointer type