Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: Performance of unaligned memory-accesses Date: Sun, 11 Aug 2019 17:07:21 -0700 Organization: None to speak of Lines: 71 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="2f44d05b13bc2f3f5103065553a9c589"; logging-data="21775"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+ametrOyrRnLtNfz3hF1JU" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:bDGSxqN6QPGzlBD7BqFvsNnMg7k= sha1:Aj6ujML26QL4ujoRJ3hXeNwZksY= Xref: csiph.com comp.lang.c++:67584 Bart writes: > On 11/08/2019 21:07, Keith Thompson wrote: >> Bart writes: >> [...] >>> On one simple C compiler I use (actually, my own) '#pragma pack(1)' >>> simply disables the padding that would otherwise be inserted to ensure >>> proper alignment. >>> >>> It doesn't consider the legality of such accesses, although the whole >>> compiler does assume the target is byte-addressable (offsets of struct >>> members are byte-offsets from the start). >> >> And what happens if a program accesses a misaligned member? >> >> #pragma pack(1) >> struct foo { >> char c; >> int i; >> } obj = { 0 }; >> printf("%d\n", obj.i); >> >> If your compiler targets x86 and/or x86_64, such an access will >> probably just work. On other targets, it might blow up -- and if >> so, I would seriously question the wisdom of claiming to support >> #pragma pack(1). > > Actually, most of the time when pack(1) is used, elements will be > properly aligned anyway. Because they will be sized and arranged > manually to get the most efficient packing. > > When done properly, then I should be able to comment out the pack(1), > and it ought to still work, and with the same sizes of structs, and the > same member offsets. Then there's no point in using pack(1), is there? But I asked specifically about a case where it causes a member to be aligned differently than it would without the pack(1). > But pack(1) can also be used to define a particular layout, in instances > where I don't need to access individual misaligned members, just to get > the right overall size. If you have struct foo { char c; int i; } (assume int is 4 bytes), and #pragma pack(1) gives the struct a size of 5 bytes, then an array of struct foo will result in misaligned members. #pragma pack(1) struct foo { char c; int i; } array[2]; One of array[0].i and array[1].i will be at an odd address. > More difficult is supporting pack(1) when a machine doesn't have > byte-addressability, but I don't know if that is common these days. It depends on what you mean by "byte-addressibility". Almost all machines can access bytes at arbitrary addresses. The question is whether they can access words at odd addresses. > (My own compilers target x64. [snip] And since x64 can access words at odd addresses, there's no problem. If you wanted to target your compiler to systems that don't support accessing words at odd addresses, you might have a problem. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */