{"id":10,"date":"2006-07-31T10:04:45","date_gmt":"2006-07-31T18:04:45","guid":{"rendered":"http:\/\/digitalvampire.org:8080\/blog\/index.php\/2006\/07\/31\/why-you-shouldnt-use-__attribute__packed\/"},"modified":"2017-07-20T00:12:25","modified_gmt":"2017-07-20T08:12:25","slug":"why-you-shouldnt-use-__attribute__packed","status":"publish","type":"post","link":"https:\/\/digitalvampire.org\/blog\/index.php\/2006\/07\/31\/why-you-shouldnt-use-__attribute__packed\/","title":{"rendered":"Why you shouldn&#8217;t use __attribute__((packed))"},"content":{"rendered":"<p>gcc supports an extension that allows structures or structure members to be marked with <code>__attribute__((packed))<\/code>, which tells gcc to leave out all padding between members.    Sometimes you need this, when you want to make sure of the layout of a structure.  For example, you might have something like<\/p>\n<pre>\r\n    struct my_struct {\r\n            uint8_t  field1;\r\n            uint16_t field2;\r\n    } __attribute__((packed));<\/pre>\n<p>Without the packed attribute, the struct will have padding between <code>field1<\/code> and <code>field2<\/code>, and that\/s no good if this struct is something that has to match hardware or be sent on a wire.<\/p>\n<p>However, it&#8217;s actively harmful to add the attribute to a structure that&#8217;s already going to be laid out with no padding.  Sometimes, when a structure needs to be laid out without padding (because of hardware or wire protocol), people are tempted to add the attribute to a struct like the following &#8220;just to let the compiler know&#8221;<\/p>\n<pre>\r\n    struct my_struct {\r\n            uint32_t  field1;\r\n            uint32_t field2;\r\n    };<\/pre>\n<p>But adding <code>__attribute__((packed))<\/code> goes further than just telling gcc that it shouldn&#8217;t add padding &#8212; it also tells gcc that it can&#8217;t make any assumptions about the alignment of accesses to structure members.  And this leads to disastrously bad code on some architectures.<\/p>\n<p>To see this, consider the simple code<\/p>\n<pre>\r\n    struct foo { int a; };\r\n    struct bar { int b; } __attribute__((packed));\r\n\r\n    int c(struct foo *x) { return x-&gt;a; }\r\n    int d(struct bar *x) { return x-&gt;b; }<\/pre>\n<p>On architectures like x86, x86-64 and powerpc, both functions generate the same code.  But take a look at what happens on ia64:<\/p>\n<pre>\r\n   0000000000000000 &lt;c&gt;:\r\n      0:       13 40 00 40 10 10       [MBB]       ld4 r8=[r32]\r\n      6:       00 00 00 00 10 80                   nop.b 0x0\r\n      c:       08 00 84 00                         br.ret.sptk.many b0;;\r\n\r\n   0000000000000010 &lt;d&gt;:\r\n     10:       09 70 00 40 00 21       [MMI]       mov r14=r32\r\n     16:       f0 10 80 00 42 00                   adds r15=2,r32\r\n     1c:       34 00 01 84                         adds r32=3,r32;;\r\n     20:       19 80 04 1c 00 14       [MMB]       ld1 r16=[r14],1\r\n     26:       f0 00 3c 00 20 00                   ld1 r15=[r15]\r\n     2c:       00 00 00 20                         nop.b 0x0;;\r\n     30:       09 70 00 1c 00 10       [MMI]       ld1 r14=[r14]\r\n     36:       80 00 80 00 20 e0                   ld1 r8=[r32]\r\n     3c:       f1 78 bd 53                         shl r15=r15,16;;\r\n     40:       01 00 00 00 01 00       [MII]       nop.m 0x0\r\n     46:       e0 70 dc ee 29 00                   shl r14=r14,8\r\n     4c:       81 38 9d 53                         shl r8=r8,24;;\r\n     50:       0b 70 40 1c 0e 20       [MMI]       or r14=r16,r14;;\r\n     56:       f0 70 3c 1c 40 00                   or r15=r14,r15\r\n     5c:       00 00 04 00                         nop.i 0x0;;\r\n     60:       11 00 00 00 01 00       [MIB]       nop.m 0x0\r\n     66:       80 78 20 1c 40 80                   or r8=r15,r8\r\n     6c:       08 00 84 00                         br.ret.sptk.many b0;;<\/pre>\n<p>gcc gets scared about unaligned accesses and generates six times as much code (96 bytes vs. 16 bytes)!  sparc64 goes similarly crazy, bloating from 12 bytes to 52 bytes:<\/p>\n<pre>\r\n   0000000000000000 &lt;c&gt;:\r\n      0:       81 c3 e0 08     retl\r\n      4:       d0 42 00 00     ldsw  [ %o0 ], %o0\r\n      8:       30 68 00 06     b,a   %xcc, 20 &lt;d&gt;\r\n\r\n   0000000000000020 &lt;d&gt;:\r\n     20:       c6 0a 00 00     ldub  [ %o0 ], %g3\r\n     24:       c2 0a 20 01     ldub  [ %o0 + 1 ], %g1\r\n     28:       c4 0a 20 02     ldub  [ %o0 + 2 ], %g2\r\n     2c:       87 28 f0 18     sllx  %g3, 0x18, %g3\r\n     30:       d0 0a 20 03     ldub  [ %o0 + 3 ], %o0\r\n     34:       83 28 70 10     sllx  %g1, 0x10, %g1\r\n     38:       82 10 40 03     or  %g1, %g3, %g1\r\n     3c:       85 28 b0 08     sllx  %g2, 8, %g2\r\n     40:       84 10 80 01     or  %g2, %g1, %g2\r\n     44:       90 12 00 02     or  %o0, %g2, %o0\r\n     48:       81 c3 e0 08     retl\r\n     4c:       91 3a 20 00     sra  %o0, 0, %o0\r\n     50:       30 68 00 04     b,a   %xcc, 60 &lt;d+0x40&gt;<\/pre>\n<p>So the executive summary is: don&#8217;t add <code>__attribute__((packed))<\/code> to your code unless you know you need it.<\/p>\n<div class=\"wp_plus_one_button\" style=\"margin: 0 0 8px 8px;float:right\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>gcc supports an extension that allows structures or structure members to be marked with __attribute__((packed)), which tells gcc to leave out all padding between members. Sometimes you need this, when you want to make sure of the layout of a structure. For example, you might have something like struct my_struct { uint8_t field1; uint16_t field2; [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-10","post","type-post","status-publish","format-standard","hentry","category-hacking"],"_links":{"self":[{"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=10"}],"version-history":[{"count":3,"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/10\/revisions"}],"predecessor-version":[{"id":638,"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/10\/revisions\/638"}],"wp:attachment":[{"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=10"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=10"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/digitalvampire.org\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}