回答
是的,對齊要求必須是相同的。顯然,一列T
必須至少與單個T
一樣嚴格對齊,否則其第一個成員將不會正確對齊。數組不能更嚴格地與其元素類型對齊的事實來自標準部分8.3.4,其說明數組是連續分配的元素子對象。考慮一下這個數組的數組:
T a[2][size];
不管的size
值,可以有兩個數組a[0]
和a[1]
之間沒有「額外」的填充,否則這違反了contiguosly分配要求。我們知道(char*)&a[1] == (char*)&a[0] + sizeof(a[0])
和sizeof(a[0]) == sizeof(T[size]) == size * sizeof(T)
。因爲這適用於任何size
,所以必須可以在任何地址上放置一個T
的數組,該數組適合單個對象(給定足夠的地址空間)。
據我所知,如果子數組的大小是對齊的倍數,那麼對齊可能與元素不同,因爲不需要填充。 [這個評論](http://stackoverflow.com/users/147192/matthieu-m)似乎是正確的答案。 – Pubby
[Whoops,this link](http://stackoverflow.com/questions/13284208/how-is-an-array-aligned-in-c-compared-to-a-type-contained/13284631#comment18111863_13284297) – Pubby
' T [2]'可以與'alignof(T)* 2'對齊,這將允許'T [2] [size]'沒有任何填充。 – Pubby
我相信陣列的對齊需求將與陣列元素的對齊需求相同。
顯然,數組的起始位置必須至少與第一個元素所要求的一樣嚴格,所以它的對齊要求不能不那麼嚴格。
數組的起始地址加上每個元素的大小必須使第二個元素充分對齊。這對元素類型的大小有一個約束,我相信這意味着填充可以在結構的末尾引入,以保持數組對齊,即使你從不在數組中使用該結構。但這並不意味着需要更嚴格的協調。
通過歸納法,如果前兩個元素都是OK的,後續元素都可以,因此給數組提供與其元素相同的對齊要求應該很好。但是,從規範中引用將是很好的。
這裏你去(對齊)**§5.3.6[expr.alignof] ** 1 /一個'alignof'表達式產生其操作數類型的對齊要求。操作數應該是* type-id *,表示一個完整的對象類型或其數組。[...] 3/[...]當對數組類型應用'alignof'時,結果應該是元素類型。 –
任何「填充」必須反映在'sizeof';不在數組中的元素必須與不在數組中的元素具有相同的大小。至於第二點,我不認爲標準否認數組有權比非數組類型有更嚴格的對齊要求(我相當肯定C++ 03,它沒有太多關於對齊開始),但實際上,對齊要求將是相同的。 –
對齊要求將相同,但有一個明顯的例外情況。一個'new char [n]'(其中'char'實際上可以是任何字符類型)的返回值必須與任何適合'n'的類型對齊。但是,請注意,此保證僅適用於「新」表達式;它不適用於'char []'類型的變量。 –
規則是相同的我相信但解釋可能會混淆。
我相信,因爲數組的每個元素將具有相同的大小,所以只有對齊第一個元素會自動對齊其餘元素,因此在元素之間永遠不會有任何填充。
這可能是真實的情況下一個微不足道的數組,但不適用於複雜的情況。
陣列的步幅可能大於元素大小,即每個單獨元素之間可能存在襯墊。
下面是一個很好的例子
struct ThreeBytesWide {
char a[3];
};
struct ThreeBytesWide myArray[100];
ThreeBytesWide陣列的每個元素都能夠被排列到四個字節邊界
編輯:所闡述的意見,提在單個元素之間有襯墊的時候,元素本身就是3個字節,並且與4個字節的邊界對齊。
該文章具有誤導性,因爲有關C/C++行爲的消息來源。在其Talk頁面中:C和C++中的「stride」和sizeof()總是相同的,即sizeof(T [N])== sizeof(T)* N。例如參見ISO14882的8.3.4: 2003(e)或ISO9899:1999(e)的6.5.2.1以及ISO9899:1999(e)的6.5.6和ISO9899:1999(e)的6.2.5-20; ISO9899的6.5.3.4-6 :1999(e)在這裏很有趣。「 –
陣列中沒有填充。如果結構在四個字節的邊界對齊,我們還會在每個結構的末尾有'sizeof(ThreeBytesWide)== 4',並且有一個未使用的字節。 –
我不知道我完全理解這兩個意見。 @BoPersson我也在說sizeof(ThreeBytesWide)會是4.所以對於一個單獨的數組,除了第一個字節之外不會有填充,除非它被封裝在一個像上面那樣的結構中。 – fayyazkl
對象數組需要是連續的,所以在對象之間不會有填充,儘管填充可以添加到對象的末尾(產生幾乎相同的效果)。 C++ Data Member Alignment and Array Packing
#include <iostream>
__declspec(align(32))
struct Str1
{
int a;
char c;
};
template<typename T>
struct size
{
T arr[10];
};
int main()
{
size<Str1> b1;
std::cout << sizeof(Str1) << std::endl; // prints 32
std::cout << sizeof(b1) << std::endl; // prints 320
std::cin.ignore();
return 0;
}
參考文獻:
這並沒有說明數組本身的對齊方式,只是關於大小。 – sharptooth
- 1. 與包含的類型相比,C++中的數組是如何對齊的? 2
- 2. 比較包含相同枚舉類型
- 3. 如何組合兩個包含相同類型的HashMap對象?
- 4. 如何在它包含相同類型
- 5. 給列表與包含它的類相同的類型
- 6. 類型球拍的類型系統與OCaml的類型系統相比如何?
- 7. 如何檢查List是否包含某種類型的對象? C#
- 8. 小巧構建包含相同對象類型的對象樹
- 9. C++中與Java泛型相比的自定義類型排序
- 10. 如何遍歷包含與對象具有相同類型的子對象的對象?
- 11. Shapeless與不同類型,但相同的標籤對齊
- 12. 自定義C#對象是否可以包含與其自身相同類型的屬性?
- 13. C#如何比較兩個變量是否是相同的類型?
- 14. 測試該列表包含相同類型的「對象」python unittest
- 15. 的類型不是與EdmEntityTypeAttribute歸因但包含在與EdmSchemaAttribute
- 16. 與C#相比,F#的性能如何?
- 17. 是否有與指針具有相同大小和對齊的整數類型?
- 18. c/C++相對包含路徑vs Makefile包含標誌
- 19. C++:沒有包含的對象的確切類型轉換
- 20. 與NHibernate使用如何查詢相關的對象包含
- 21. 獲取包含泛型類型與ClassTag
- 22. 如何使用Fluent NHibernate映射包含與父類型相同類型的實體的列表?
- 23. 相互包含在C++ ..它是如何工作的?
- 24. C#中的ArrayList是否可以包含各種類型的對象?
- 25. Android的 - 如何對齊相對的TextView
- 26. 如何比較幻像類型相對於幻像類型參數的實例?
- 27. 包含派生模型相關類
- 28. 相互包含中斷類型
- 29. C++類包裝/成員對齊
- 30. 使用未聲明的類型錯誤:如何比較對象與類類型?
我很好奇,爲什麼這很重要? – Pubby
@Pubby:我正在審查代碼,並且我發現了一些關於數組和對齊要求的非常好奇的評論,我幾乎可以肯定的是評論是blsht,但是想要驗證。 – sharptooth