假設我有如下所示的結構:用戶代碼可以安全地使用struct padding嗎?
struct Struct {
char Char;
int Int;
};
和sizeof(int)
大於一併且編譯器添加填充用於Char
成員變量 - 是允許改變填充字節的值的編譯器生成的代碼?
我的意思是如果我使用指針算術,並將一些數據寫入圍繞Char
成員變量的填充字節中,後來做variable.Char =
賦值有可能由編譯器生成的代碼也會覆蓋一些填充字節?
假設我有如下所示的結構:用戶代碼可以安全地使用struct padding嗎?
struct Struct {
char Char;
int Int;
};
和sizeof(int)
大於一併且編譯器添加填充用於Char
成員變量 - 是允許改變填充字節的值的編譯器生成的代碼?
我的意思是如果我使用指針算術,並將一些數據寫入圍繞Char
成員變量的填充字節中,後來做variable.Char =
賦值有可能由編譯器生成的代碼也會覆蓋一些填充字節?
以下句子是錯誤:不,它不會覆蓋填充字節。但使用它可能不是一個好習慣。如果你需要它,在那裏添加成員變量。
我研究基於指示(正確)說我笨評論:
C標準有「附件J」第J.1不確定的行爲。它說,「在結構或聯合中存儲值時填充字節的值」。其含義是編譯器可以生成任何想要將數據寫入結構的指令,這可能允許它在成員之後覆蓋填充。
沒有什麼可以阻止編譯器覆蓋填充。 – 2010-01-06 13:54:35
是的,爲什麼不呢? – jalf 2010-01-06 13:59:22
Mea culpa。你是對的。沒有什麼可以阻止它。 C標準的附錄J列出了「結構中填充字節的值」未指定。 – 2010-01-06 14:46:31
你當然可以在那裏寫東西,而memset
-這樣的結構的一個實例。但是,這是不安全,從來不是一個好主意這樣做。另一天,另一位開發人員在某處放置#pragma
或者添加了一個成員來聲明結構,並且您的代碼會以許多奇怪和奇特的方式爆炸,這可能需要很長時間才能調試。
這樣做的唯一原因就像插件evilly欺騙主機應用程序存儲額外的數據。
雖然不這樣做,因爲在未來的某個時間點會打破,這將是所有相關人員的嚴重頭痛。
@nobugz,我認爲這是一個有效的問題。在設置值之前,您已將memset結構設置爲0,您可以稍後使用memcmp來比較兩個結構,但前提是編譯器不觸及填充字節。 – quinmars 2010-01-06 14:29:19
不要混淆帶有類和結構的填充,memset或memcpy。 **更安全的**和**更強大的**方法是實現讀取和寫入打包緩衝區的方法(例如'unsigned char []')。該保險值得額外的可執行空間和時間。 – 2010-01-06 17:44:01
@Thomas Matthews,我想你誤解了我。我在談論比較兩個結構,請參閱http://stackoverflow.com/questions/141720/how-do-you-compare-structs-for-equality-in-c/141791#141791 – quinmars 2010-01-06 19:08:24