【问题标题】:In C, does a pointer to a structure always point to its first member?在 C 中,指向结构的指针是否总是指向其第一个成员?
【发布时间】:2011-11-10 20:53:58
【问题描述】:

假设我有许多 C 结构,我希望使用一组特定的函数对其进行操作。

我想知道以下方法是否合法:

typedef struct Base {
     int exampleMember;
     // ...
} Base;

typedef struct Foo {
     Base base;
     // ...
} Foo;

typedef struct Bar {
     Base base;
     // ...
} Bar;

void MethodOperatesOnBase(void *);

void MethodOperatesOnBase(void * obj)
{
     Base * base = obj;
     base->exampleMember++;
}

在示例中,您会注意到 FooBar 结构都以 Base 成员开头。

而且,在MethodOperatesOnBase 中,我将void * 参数转换为Base *

我想将指向Bar 的指针和指向Foo 的指针传递给此方法,并依赖结构的第一个成员是Base 结构。

这是可以接受的,还是我需要注意一些(可能是特定于编译器的)问题? (比如某种包装/填充方案会改变结构的第一个成员的位置?)

【问题讨论】:

  • 有什么理由不只使用 C++?
  • 是的。但要点很好。我正在尝试为我的项目中有限数量的结构模仿一个超级简单的继承机制。
  • 我明白你在说什么,但我不能为这个项目。
  • Is this homework? 离开学校 10 年了,但谢谢。哈哈
  • @Jonathan Grynspan:这是一个合理的问题。假设你的程序有 10,000 行长,并且用 C 语言编写。那么你有大约 100 行需要做这个结构双关语的地方。在这种情况下,花更多的精力来保持整个程序在 C 中的兼容性可能是值得的。

标签: c


【解决方案1】:

是的,C 标准特别保证这会起作用。

(C1x §6.7.2.1.13:“一个指向结构对象的指针,经过适当转换,指向它的初始成员......反之亦然。作为结构对象,可能有未命名的填充,但不是在它的开头.")

【讨论】:

【解决方案2】:

我不反对任何关于您的建议可行的答案,但是为了进行更完整的讨论(不建议您使用 C++!),为什么不做类似的事情

typedef struct Base ...  /* The types defined exactly as before */
typedef struct Foo ...
typedef struct Bar ...

/* The function takes a Base* since that is what it actually works with*/
void MethodOperatesOnBase(Base* pbase)
{
    /* Do something... */
}

/* Now call it like this: */
Foo foo;
Bar bar;

MethodOperatesOnBase(&foo.base);
MethodOperatesOnBase(&bar.base);

是否有某些原因不起作用,您需要使用void *?我不认为这是更多的工作,它确实具有类型安全的优势。

【讨论】:

  • 嗯,在我的特殊情况下,原因是因为FooBar 被暴露为不透明的指针。
  • @Steve:好的,所以调用者不能引用base 成员,你必须通过重新解释结构指针来做到这一点。这是有道理的,谢谢你的澄清。
【解决方案3】:

整个 gtk+ 就是这样实现的。我想不出更好的例子。看看http://git.gnome.org/browse/gtk+/tree/gtk/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 2023-03-12
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多