2011-10-11 84 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 需要一個診斷以及其他已添加診斷的其他診斷程序。