【问题标题】:GCC Casting Pointer to Incompatible TypeGCC 将指针转换为不兼容的类型
【发布时间】:2017-05-24 02:50:17
【问题描述】:

当我使用 GCC 编译时,我有一个可以工作的 C 代码,但我试图找出代码是否可以正常工作,或者是因为 GCC 按照我的设计预期处理了该代码。

注意 我并不是要“修复”它。我正在尝试了解编译器

这是我所拥有的:

iexample.h

#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;

}

ma​​in.c

#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() 中分配指针,

warning: assignment from incompatible pointer type 

只要我有“struct MyIf myinterface”作为结构的第一个成员,代码就可以工作,这是设计使然(我喜欢在脚上开枪)

现在,虽然我分配了不兼容的指针类型,并且 C 规范说行为未定义,但 GCC 或其他编译器是否对如何处理这种情况做出任何设计声明?我几乎可以发誓,由于结构内存的布局方式,这应该可以工作,但我找不到证据。

谢谢

【问题讨论】:

    标签: c pointers gcc struct


    【解决方案1】:

    C11 标准 6.7.2.1 结构和联合说明符:

    在结构对象中,非位域成员和 位域所在的单元的地址增加 声明它们的顺序。指向结构的指针 适当转换的对象指向其初始成员(或 如果该成员是位域,则到它所在的单元 驻留),反之亦然。内部可能有未命名的填充 一个结构对象,但不是在它的开头。

    所以它应该可以工作,因为您只访问第一个结构成员。但是,我相信您明白,这是一个非常糟糕的主意。如果您将此代码移植到 C++ 并让一些 Obj1 成员虚拟化,这将立即失败。

    【讨论】:

    • +1 给出了关于它如何失败并显示规范的不那么微不足道的例子。我找错地方了。
    • @M.M 是吗?给定的引用不是表明它必须按照标准以这种方式工作吗?
    • @sepp2k 不,报价只涉及结构布局
    • @M.M 它说结构的地址总是等于第一个成员的地址,对吧?因此,当转换为成员的类型时,指向结构的有效指针是否也将是指向第一个成员的有效指针?
    • sepp2k,我得出的结论是 sepp2k 是错误的。这段代码是正确的。搜索“面向对象的 C pdf”会显示使用类似技术的结果。
    猜你喜欢
    • 1970-01-01
    • 2016-01-27
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多