很明顯,在C cannot insert padding between their elements中的數組。但是,是否有任何規則說他們不能在整個陣列的尾端處添加尾部填充?數組可以有尾部填充嗎?
即,這個程序保證在任何地方都能得到相同的結果嗎?
#include <stdio.h>
int main(void) {
typedef char a[3];
typedef a b[3];
printf("%zu %zu\n", sizeof(a), sizeof(b)); // -> 3 9
}
至於我可以工作,加入了尾隨字節或五的a
大小,也許在一個錯誤的優化的嘗試,就不會突破數組訪問規則(b[1][1]
仍然恰好映射到*(&b + sizeof(a) * 1 + 1)
不管其包含的a
對象的大小,並且訪問超出所包含的a
的長度是UB)。
我找不到在C標準中的任何地方,它實際上說直接說數組的大小是元素類型的大小乘以元素的數量。 6.5.3.4只說sizeof
返回數組中的「字節數」(它確實給出sizeof array/sizeof array[0]
作爲代碼示例,但它只是一個示例 - 它並不是說它必須工作,它不給出任何細節)。
隱式保證對於編寫依賴於確切數據佈局的便攜式代碼很有用,例如,經過打包的RGB值:
typedef uint8_t RGB[3];
RGB * data = ...;
glColorPointer(3, GL_UNSIGNED_BYTE, 0, data);
(OK這樣的OpenGL可以接受步幅值,所以這是一個壞榜樣,但你明白了吧)
對於這個問題,我從廣泛的概念(即使假設標準中的例子),你可以用sizeof
得到一個數組元素的數量,無論如何這在任何地方都可能是真的 - 是否有任何已知的情況?
填充的含義是使數據對齊。在你的情況下,我相信所有3的char數組的大小都是3,但如果你在之後聲明一個int,那麼可能會有1或5個填充。一個好的c編譯器不會做額外的工作,這很難預測。但如果您談論的是可移植性,我認爲最好是在目標平臺上重新編譯代碼,或者如果平臺差異很大,則可以進行交叉編譯。 – HuStmpHrrr 2014-11-23 19:36:48
「,並沒有給出任何細節」 - 它確實說計算數組中的元素數量。你說得對,那只是一個例子,而這個例子並不是規範的。 – hvd 2014-11-23 19:39:26
通過查看後續子句,可以間接推斷出數組沒有這種填充:「當應用於具有結構或聯合類型的操作數時,結果是此類對象中的總字節數,包括內部和尾部填充。」 - 在結構和聯合中顯式引用了填充,而在數組中缺少這種引用使我相信數組中不能有這種填充。 – 2014-11-23 19:41:32