title: Are there any guarantees about C struct order?
body: <p>I've used structs extensively and I've seen some interesting things, especially <code>*value</code> instead of <code>value-&gt;first_value</code> where value is a pointer to struct, <code>first_value</code> is the very first member, is <code>*value</code> safe?</p>
  
  <p>Also note that sizes aren't guaranteed because of alignment, whats the alginment value based on, the architecture/register size?</p>
  
  <p>We align data/code for faster execution can we tell compiler not to do this? so maybe we can guarantee certain things about structs, like their size?</p>
  
  <p>When doing pointer arithmetic on struct members in order to locate member offset, I take it you do <code>-</code> if little endian <code>+</code> for big endian, or does it just depend on the compiler?</p>
  
  <p><i>what does malloc(0) really allocate?</i></p>
  
  <p><b>The following code is for educational/discovery purposes, its not meant to be of production quality.</b> </p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  
  int main()
  {
      printf("sizeof(struct {}) == %lu;\n", sizeof(struct {}));
      printf("sizeof(struct {int a}) == %lu;\n", sizeof(struct {int a;}));
      printf("sizeof(struct {int a; double b;}) == %lu;\n", sizeof(struct {int a; double b;}));
      printf("sizeof(struct {char c; double a; double b;}) == %lu;\n", sizeof(struct {char c; double a; double b;}));
  
      printf("malloc(0)) returns %p\n", malloc(0));
      printf("malloc(sizeof(struct {})) returns %p\n", malloc(sizeof(struct {})));
  
      struct {int a; double b;} *test = malloc(sizeof(struct {int a; double b;}));
      test-&gt;a = 10;
      test-&gt;b = 12.2;
      printf("test-&gt;a == %i, *test == %i \n", test-&gt;a, *(int *)test);
      printf("test-&gt;b == %f, offset of b is %i, *(test - offset_of_b) == %f\n",
          test-&gt;b, (int)((void *)test - (void *)&amp;test-&gt;b),
          *(double *)((void *)test - ((void *)test - (void *)&amp;test-&gt;b))); // find the offset of b, add it to the base,$
  
      free(test);
      return 0;
  }
  </code></pre>
  
  <p>calling <code>gcc test.c</code> followed by <code>./a.out</code>
  I get this:</p>
  
  <pre><code>sizeof(struct {}) == 0;
  sizeof(struct {int a}) == 4;
  sizeof(struct {int a; double b;}) == 16;
  sizeof(struct {char c; double a; double b;}) == 24;
  malloc(0)) returns 0x100100080
  malloc(sizeof(struct {})) returns 0x100100090
  test-&gt;a == 10, *test == 10 
  test-&gt;b == 12.200000, offset of b is -8, *(test - offset_of_b) == 12.200000
  </code></pre>
  
  <p><b>Update</b>
  this is my machine: </p>
  
  <p><code>gcc --version</code></p>
  
  <pre><code>i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
  Copyright (C) 2007 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  </code></pre>
  
  <p><code>uname -a</code></p>
  
  <pre><code>Darwin MacBookPro 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
  </code></pre>