(Translated by https://www.hiragana.jp/)
数据结构对齐 - 维基百科,自由的百科全书

かずすえ结构对齐

かずすえ结构对齐ほどしき编译きさき資料しりょうざい記憶きおくたい內的佈局あずか使用しよう方式ほうしき包括ほうかつさん方面ほうめん内容ないようかずすえ对齐かずすえ结构填たかし(padding)あずかつつみいれ(packing)。

现代计算つくえCPU一般いっぱん32もとある64もとだい小作こさく对齐,以32もとてき計算けいさん舉例,每次まいじ連續れんぞくてき4もとぐみためいち區間くかん,だい一個位元組的位址位在每次CPUつめ資料しりょう大小だいしょうてきあたりかいじょう,じょ此之がい,如果よう访问てき变量ぼつゆう对齐,可能かのうかいさわ总线错误

とう資料しりょうしょう于计さんつくえてき(word)尺寸しゃくすん可能かのう几个資料しりょうざいいち个字ちゅうしょうつつみいれ(packing)。

许多编程语言动处かずすえ结构对齐。Ada语言[1][2] PL/I,[3] Pascal,[4] ぼうC语言あずかC++实现, D语言,[5] Rust,[6] あずか汇编语言まこと许特别控せい对齐てき方式ほうしき

てい

编辑

うちそんaしょうn对齐aこれnてき倍数ばいすうn应是2てき),也可以理解りかい為當ためとう访问てきすうすえ长度为n 节時,すうすえn节对齐。如果ないそん对齐,しょうさくmisaligned

うちそんゆび对齐てき,如果它所ゆびてきすうすえ对齐てき指向しこう聚合すうすえ(aggregate data,如structあるすう组)对齐てきとう且仅とう它的ごと个组なりすうすえ对齐てき

体系たいけい结构

编辑

だい多数たすうRISC处理ざい载或そん储指れい访问错位てき时,かい产生一个对齐错误。这允许操作そうさけい使用しよう其他指令しれいらい拟错てき访问。れい如,对齐错误处理ほどじょ以使用字ようじ节加载或そん储(其总对齐てきらい拟更だいてき载或そん指令しれい

いち些架构,如MIPSゆう特殊とくしゅてき无对齐加载和そん指令しれい一条いちじょう无对齐的载指れい具有ぐゆう最低さいてい节地てきないそんちゅう获取节,另一条指令从具有最高字节地址的内存字中获取字节。どう样的,store-highstore-low指令しれいぶん别在较高较低てきないそんちゅうそん储相应的节。

DEC Alpha构对对齐てき载和そん储采ようりょう两步ほうだい一步是将上层和下层的内存字加载到独立的寄存器中。だい二步是使用类似于MIPS指令しれいてき特殊とくしゅてい/こう指令しれいらいひっさげあるおさむあらためないそんつう过将おさむあらためきさきてきないそんそん储到ないそんちゅう,就完成かんせいりょう一个无对齐存储。造成ぞうせい这种复杂せいてき原因げんいん最初さいしょてきAlpha构只のう读取あるうつしいれ32ある64てき值。这被证明一个严重的限制,经常导致だい码臃肿和性能せいのうけい。为了解りょうかい决这个限せいざい最初さいしょてき构中加入かにゅうりょういち个名为 "节字扩展"(BXW)てき扩展。它包括ほうかつ和字わじてき载和そん指令しれい

いん为这些指令しれい正常せいじょうてきないそん载和そん储指れいさらだいさら慢,所以ゆえんただゆうざい必要ひつよう时才使用しよう它们。いち些CC++编译ゆういち个 "无对齐 "属性ぞくせい以应よう于需よう无对齐指れいてきゆび针。

x86体系たいけい构最はつ要求ようきゅうないそん对齐。いちSSE2指令しれい要求ようきゅうすうすえ128とく(16节)对齐。ゆう些CPU指令しれいよう于未对齐访问如MOVDQU。读写ないそん操作そうさ仅在对齐时才原子げんしてき

C语言structざいx86うえてき对齐

编辑

C语言かずすえ结构内的ないてきなり员按あきらさききさき顺序ざいないそんちゅうそん储。

だま认对齐

编辑

结构たいちゅうまい个成员的类型通常つうじょうゆう一个默认的对齐方式,也就说,じょほどじょ员另ゆう要求ようきゅういや则它はたざい一个预先确定的边界上对齐。以下いか典型てんけいてき对齐方式ほうしきほろVisual C++)、Borland/CodeGearえいCodeGearC++Builder)、Digital MarsえいDigital Mars(DMC)GNUGCCてき编译ざい为32x86编译时有效ゆうこう

いちcharいち个字节)变量はた1节对齐。

いちshort(两个节)变量はた2节对齐的。

いちintよん个字节)变量はた4节对齐的。

いちlongよん个字节)变量はた4节对齐。

いちfloatよん个字节)变量はた4节对齐的。

いちdouble(8个字节)变量ざいWindowsじょう8节对齐的,ざいLinuxじょう4节对齐的(よう-malign-double编译时选项是8节)。

いちlong long(8个字节)变量はた4节对齐。

いちlong double(C++BuilderDMC为10个字节,Visual C++为8个字节,GCC为12个字节)变量ざいC++Builderじょうはた8节对齐,DMC为2节对齐,Visual C++为8节对齐,GCC为4节对齐。

にんなにゆびよん个字节)みやこすすむ4节对齐的。(れい如:char*, int*)

あずか32けい统相LP64 64けい统在对齐方面ほうめんただ一值得注意的区别是。

いちlongはち个字节)变量はた8节对齐的。

いちdouble(8个字节)变量はた8节对齐的。

いちlong long(8个字节)变量はた8节对齐的。

いちlong doubleざいVisual C++ちゅう8个字节,ざいGCCちゅう16个字节)变量ざいVisual C++ちゅう8节对齐的,ざいGCCちゅう16节对齐的。

にんなにゆびはち个字节)变量はた8节对齐的。

ゆう些数すえ类型决于实现方式ほうしき

指定してい对齐

编辑

いち些编译器(Microsoft,[7] Borland, GNU,[8]ひとしとう使用しよう#pragma directive指定してい对齐てきつつみいれ(packing)。れい如:

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */

struct MyPackedData
{
    char Data1;
    long Data2;
    char Data3;
};

#pragma pack(pop)   /* restore original alignment from stack */

这个结构ざい32けい统的大小だいしょう为6节。

かけしょうpackingあずか#pragma pack

编辑

Microsoft编译てき项目かけしょうpacking(编译选项/Zp)あずか#pragma pack指令しれい#pragma pack指令しれい仅能减少packing尺寸しゃくすん[9]

まいり

编辑

参考さんこう文献ぶんけん

编辑
  1. ^ Ada Representation Clauses and Pragmas. GNAT Reference Manual 7.4.0w documentation. [2015-08-30]. (原始げんし内容ないようそん档于2015-10-13). 
  2. ^ F.8 Representation Clauses. SPARCompiler Ada Programmer's Guide (PDF). [2015-08-30]. (原始げんし内容ないようそん (PDF)于2021-12-16). 
  3. ^ IBM System/360 Operating System PL/I Language Specifications (PDF). IBM. July 1966: 55–56 [2017-11-21]. C28-6571-3. (原始げんし内容ないようそん (PDF)于2019-05-29). 
  4. ^ Niklaus Wirth. The Programming Language Pascal (Revised Report) (PDF): 12. July 1973 [2017-11-21]. (原始げんし内容ないよう (PDF)そん档于2015-03-15). 
  5. ^ Attributes - D Programming Language: Align Attribute. [2012-04-13]. (原始げんし内容ないようそん档于2012-04-09). 
  6. ^ The Rustonomicon - Alternative Representations. [2016-06-19]. (原始げんし内容ないようそん于2016-05-09). 
  7. ^ pack. [2017-11-21]. (原始げんし内容ないようそん于2017-03-28). 
  8. ^ 6.58.8 Structure-Packing Pragmas. [2017-11-21]. (原始げんし内容ないようそん于2017-01-08). 
  9. ^ Working with Packing Structures. MSDN Library. Microsoft. 2007-07-09 [2011-01-11]. (原始げんし内容ないようそん于2012-10-18). 

外部がいぶ链接

编辑