{"id":24013,"date":"2007-12-27T10:00:00","date_gmt":"2007-12-27T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/12\/27\/if-you-need-anything-other-than-natural-alignment-you-have-to-ask-for-it\/"},"modified":"2007-12-27T10:00:00","modified_gmt":"2007-12-27T10:00:00","slug":"if-you-need-anything-other-than-natural-alignment-you-have-to-ask-for-it","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20071227-00\/?p=24013","title":{"rendered":"If you need anything other than natural alignment, you have to ask for it"},"content":{"rendered":"<p>\nIf you need variables to be aligned a particular way,\nyou need to ask for it.\n<\/p>\n<blockquote CLASS=\"q\">\n<p>\nLet&#8217;s say I have the following code:\n<\/p>\n<pre>\nvoid fn()\n{\n int a;\n char b;\n long c;\n char d[10];\n}\n<\/pre>\n<p>\nWhat would the alignment of the starting adresses of a,b,c and d be?\n<\/p>\n<p>\nWhat would the alignment be if the memory were allocated on heap?\n<\/p>\n<p>\nIf this alignment varies for different data types\nwithin the same translation unit,\nis there a way to force uniform alignment for all types?\n<\/p>\n<\/blockquote>\n<p>\nIf you need a particular alignment, you have to ask for it.\nBy default,\nall you can count on is that\nvariables are aligned according to their natural requirements.\n<\/p>\n<p>\nFirst, of course, there is no guarantee that local variables\neven reside on the stack.\nThe optimizer may very well decide that particular local\nvariables can reside in registers, in which case it has no\nalignment at all!\n<\/p>\n<p>\nThere are a few ways to force a particular alignment.\nThe one that fits the C language standard is to use a union:\n<\/p>\n<pre>\nunion char_with_int_alignment {\n char ch;\n int Alignment;\n} u;\n<\/pre>\n<p>\nGiven this union, you can say <code>u.ch<\/code> to obtain a\ncharacter whose alignment is suitable for an integer.\n<\/p>\n<p>\nThe Visual C++ compiler supports a declaration specifier to\noverride the default alignment of a variable.\n<\/p>\n<pre>\ntypedef struct __declspec(align(16)) _M128 {\n    unsigned __int64 Low;\n    __int64 High;\n} M128, *PM128;\n<\/pre>\n<p>\nThis structure consists of two eight-byte members.\nWithout the <code>__declspec(align(#))<\/code> directive,\nthe alignment of this structure would be 8-byte,\nsince that is the alignment of the members with the most\nrestrictive alignment.\n(Both <code>unsigned __int64<\/code> and\n<code>__int64<\/code> are naturally 8-byte-aligned.)\nBut with the directive, the aligment is expanded to 16&nbsp;bytes,\nwhich is more restrictive than what the structure normally would be.\nThis particular structure is declared with more restrictive\nalignment because it is intended to be use to hold 128-bit values\nthat will be used by the 128-bit XMM registers.\n<\/p>\n<p>\nA third way to force alignment with the Visual C++ compiler\nis to use the <code>#pragma pack(#)<\/code> directive.\n(There is also a &#8220;push&#8221; variation of this pragma which remembers\nthe previous ambient alignment, which can be restored by\na &#8220;pop&#8221; directive.\nAnd the <code>\/Zp#<\/code> directive allows you to specify this\npragma from the compiler command line.)\nThis directive specifies that members can be placed at alignments\nsuitable for <code>#<\/code>-byte objects rather than their natural\nalignment requirements, if the natural alignment is more restrictive.\nFor example, if you set the pack alignment to 2, then all objects\nthat are bigger than two bytes will be aligned\nas if they were two-byte objects.\nThis can cause 32-bit values and 64-bit values to become mis-aligned;\nit is assumed that you know what you&#8217;re doing any can compensate\naccordingly.\n<\/p>\n<p>\nFor example, consider this structure whose natural alignment\nhas been altered:\n<\/p>\n<pre>\n#pragma pack(1)\nstruct misaligned_members {\n WORD w;\n DWORD dw;\n BYTE b;\n};\n<\/pre>\n<p>\nGiven this structure, you cannot pass the address of the\n<code>dw<\/code> member to a function that expects a\npointer to a <code>DWORD<\/code>,\nsince the ground rules for programming\nspecify that all pointers must be aligned unless unaligned\npointers are explicitly permitted.\n<\/p>\n<pre>\nvoid ExpectsAlignedPointer(DWORD *pdw);\nvoid UnalignedPointerOkay(UNALIGNED DWORD *pdw);\nmisaligned_members s;\nExpectsAlignedPointer(&amp;s.dw); \/\/ wrong\nUnalignedPointerOkay(&amp;s.dw);  \/\/ okay\n<\/pre>\n<p>\nWhat about the member <code>w<\/code>?\nIs it aligned or not?\nWell, it depends.\n<\/p>\n<p>\nIf you allocate a single structure on the heap,\nthen the <code>w<\/code> member is aligned,\nsince heap allocations are always aligned in a manner suitable\nfor any fundamental data type.\n(I vaguely recall some possible weirdness with 10-byte floating point\nvalues, but that&#8217;s not relevant to the topic at hand.)\n<\/p>\n<pre>\nmisaligned_members *p = (misaligned_members)\n    HeapAllocate(hheap, 0, sizeof(misaligned_members));\n<\/pre>\n<p>\nGiven this code fragment, the member\n<code>p-&gt;w<\/code> is aligned since the entire structure\nis suitably aligned, and therefore so too is <code>w<\/code>.\nIf you allocated an array, however, things are different.\n<\/p>\n<pre>\nmisaligned_members *p = (misaligned_members)\n    HeapAllocate(hheap, 0, 2*sizeof(misaligned_members));\n<\/pre>\n<p>\nIn this code fragment, <code>p[1].w<\/code> is not aligned\nbecause the entire <code>misaligned_members<\/code> structure\nis 2+4+1=7 bytes in size since the packing is set to&nbsp;1.\nTherefore, the second structure begins at an unaligned offset\nrelative to the start of the array.\n<\/p>\n<p>\nOne final issue is the expectations for alignment when using\nheader files provided by an outside component.\nIf you are writing a header file that will be consumed by others,\nand you require special alignment, you need to say so explicitly\nin your header file,\nbecause you don&#8217;t control the code that will be including your\nheader file.\nFurthermore, if your header file changes any compiler settings,\nyou need to restore them before your header file is complete.\nIf you don&#8217;t follow this rule, then you create the situation where\na program stops working if a program changes the order in which\nit includes seemingly-unrelated header files.\n<\/p>\n<pre>\n\/\/ this code works\n#include &lt;foo.h&gt;\n#include &lt;bar.h&gt;\n\/\/ this code doesn't\n#include &lt;bar.h&gt;\n#include &lt;foo.h&gt;\n<\/pre>\n<p>\nThe problem was that <code>bar.h<\/code> changed the default\nstructure alignment and failed to return it to the original value\nbefore it was over.\nAs a result, in the second case,\nthe structure alignment for the <code>foo.h<\/code> header file\ngot &#8220;infected&#8221; and no longer matched the structure alignment\nused by the <code>foo<\/code> library.\n<\/p>\n<p>\nYou can imagine an analogous scenario where deleting a header file can\ncause a program to stop working.\n<\/p>\n<p>\nTherefore, if you&#8217;re writing a header file that will be used by others,\nand you require nonstandard alignment for your structures,\nyou should use this pattern to change the default alignment:\n<\/p>\n<pre>\n#include &lt;pshpack1.h&gt; \/\/ change alignment to 1\n... stuff that assumes byte packing ...\n#include &lt;poppack.h&gt;  \/\/ return to original alignment\n<\/pre>\n<p>\nIn this way, you &#8220;leave things the way you found them&#8221;\nand avoid the mysterious infection scenarios described above.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you need variables to be aligned a particular way, you need to ask for it. Let&#8217;s say I have the following code: void fn() { int a; char b; long c; char d[10]; } What would the alignment of the starting adresses of a,b,c and d be? What would the alignment be if the [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-24013","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>If you need variables to be aligned a particular way, you need to ask for it. Let&#8217;s say I have the following code: void fn() { int a; char b; long c; char d[10]; } What would the alignment of the starting adresses of a,b,c and d be? What would the alignment be if the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/24013","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=24013"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/24013\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=24013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=24013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=24013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}