2011-10-11 83 views
7

我已阅读,如果你声明两个结构是这样的:此代码是否由C标准保证?

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, c地址偏移量是相同的在struct Nodestruct DerivedNode之内。因此,您可以从中获得一种多态性,您可以在其中强制传递一个DerivedNode指针,无论通常会采用哪个节点指针。

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

+0

你在几处忘了'struct'关键字,不是? –

+0

@Jens哦,可能吧。对不起 –

回答

13

这是保证按标准工作。成员结构被奠定出的顺序依次指定和第一构件总是出现在偏离ANSI C标准0

相关摘录:

的结构是一种由以下组成的序列的成员,其存储按有序顺序分配。

这表示会员按顺序排列。

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

的意味着第一构件被放置在偏移0

注:TC3 2007年9月草案:从ISO/IEC 9899的节6.7.2.1截取标准摘录。

3

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

但通常这是不好的做法。我想不出太多的情况下,你不能说

struct Node *regularNode = &myDerivNode.base; 

这是更清晰,不易出错的情况下,修改后您的结构。

+0

+1我完全同意这一点。 –

+0

情况是我在一个数据结构类中,在1975年我被困在一个单独的分支(等待它..)二分查找中。 :P –

1

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

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

[-pedantic]发现一些非ISO的做法,但并不是所有的---只有那些 其ISO C 需要一个诊断以及其他已添加诊断的其他诊断程序。