这个代码是否由C标准保证?

时间:2011-10-11 11:38:22

标签: c struct

我已经读过,如果你声明这样的两个结构:

struct Node {
   int a, b, c;
};

struct DerivedNode {
   struct Node base;
   int d, e, f;
};

然后您可以像这样使用指针:

struct DerivedNode myDerivedNode; 
struct Node *regularNode = (struct Node *) &myDerivedNode;

regularNode->a = 3;

换句话说,a, b, cstruct Node内的struct DerivedNode地址偏移量相同。所以你可以从中获得一种多态性,在那里你可以传递强制(struct Node *) - 演员DerivedNode指针,无论在哪里通常都会采用Node指针。

我的问题是这种行为是否得到保证。我知道有一些奇怪的内存对齐问题,编译器有时会重新排序字段以实现更好的内存打包。 base字段是否会位于struct DerivedNode的开头?

的任何位置

3 个答案:

答案 0 :(得分:13)

这保证符合标准。结构中的成员按照您指定的顺序按顺序排列,第一个成员始终显示在偏移0处。

ANSI C标准的相关摘录:

  

结构是由一系列成员组成的类型,其存储按有序顺序分配。

这说明成员按顺序排列。

  

结构对象中可能有未命名的填充,但不在其开头。

表示第一个成员位于偏移0处。

注:标准摘录摘自ISO / IEC 9899:TC3 2007年9月草案第6.7.2.1节。

答案 1 :(得分:3)

正如大卫所述,只要base仍然是DerivedNode中的第一个元素,就可以保证这一点。

但通常这是不好的做法。我无法弄清楚你不能说的很多情况

struct Node *regularNode = &myDerivNode.base;

如果您稍后修改结构,则更清晰,更不容易出错。

答案 2 :(得分:1)

这不会回答你的问题,但是一个关心编写标准ANSI(ISO)C的人可以用gcc -pedantic-pedantic-errors编译他的代码。这些选项应该在非标准代码行上引发编译警告/错误。

请注意,这不是100%有效,来自man gcc

  

[ - pedantic]发现了一些非ISO实践,但不是全部 - 只有那些   哪个ISO C 需要诊断,以及其他一些诊断   诊断已被添加。