title: Am I doing something wrong or is this a bug in Go's C compiler?
body: <p>So I'm porting <a href="http://code.google.com/p/xxhash/" rel="nofollow">xxhash</a> from using cgo to Go's native 9p C, however I'm running into a rather weird problem.</p>
  
  <p>The hash function works perfectly fine if called as a cgo function, however if I try to use the "native" version it returns the wrong hash.</p>
  
  <p>I know enough C to get it working, but before reporting the issue, I want to make sure I'm not doing anything wrong.</p>
  
  <p><a href="https://gist.github.com/OneOfOne/fdab6439ea89871e0769" rel="nofollow">gist</a></p>
  
  <p><strong><code>xxhash.go</code>:</strong></p>
  
  <pre><code>//#include "xxhash_9p.c"
  //import "C" //uncomment this and comment the next line for the cgo version
  func XXH32_test(in unsafe.Pointer, l uint32, seed uint32) uint32
  
  
  func GoXXH32(in []byte, seed uint32) (h uint32) {
      //omitted, full version in the gist above
  }
  
  func main() {
      b := []byte("ABCDEFGLAALSDLSD:LSDL:DL:DL:SDL:SL:DSL:DL:DSL:DL:{W{EOQWExzghp[[")
      fmt.Println(XXH32_test(unsafe.Pointer(&amp;b[0]), uint32(len(b)), 0)) //uncomment this and comment the next line for the cgo version
      //fmt.Println(C.XXH32_test(unsafe.Pointer(&amp;b[0]), C.uint(len(b)), 0))
      fmt.Println(GoXXH32(b, 0)) //this is tested against the C implementation and it's the right hash.
  }
  </code></pre>
  
  <p><strong><code>xxhash_9p.c</code>:</strong></p>
  
  <pre><code>#define PRIME32_1   2654435761U
  #define PRIME32_2   2246822519U
  #define PRIME32_3   3266489917U
  #define PRIME32_4    668265263U
  #define PRIME32_5    374761393U
  
  #define U32 unsigned int
  typedef struct _U32_S { U32 v; } U32_S;
  #define A32(x) (((U32_S *)(x))-&gt;v)
  
  U32 ·XXH32_test(const void* input, U32 len, U32 seed) {
  //static U32 XXH32_test(const void* input, U32 len, U32 seed) {
      const char* p = (const char*)input;
      const char* bEnd = p + len;
      U32 h32;
  
      #define XXH_get32bits(p) A32(p)
      #define XXH_rotl32(x,r) ((x &lt;&lt; r) | (x &gt;&gt; (32 - r)))
  
      if (len&gt;=16) {
          const char* const limit = bEnd - 16;
          U32 v1 = seed + PRIME32_1 + PRIME32_2;
          U32 v2 = seed + PRIME32_2;
          U32 v3 = seed + 0;
          U32 v4 = seed - PRIME32_1;
          do
          {
              v1 += XXH_get32bits(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
              v2 += XXH_get32bits(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
              v3 += XXH_get32bits(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
              v4 += XXH_get32bits(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
          } while (p&lt;=limit);
  
          h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
      }
      else
      {
          h32  = seed + PRIME32_5;
      }
  
      h32 += (unsigned long) len;
      while (p&lt;=bEnd-4) {
          h32 += XXH_get32bits(p) * PRIME32_3;
          h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
          p+=4;
      }
  
      while (p&lt;bEnd) {
          h32 += (*p) * PRIME32_5;
          h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
          p++;
      }
  
      h32 ^= h32 &gt;&gt; 15;
      h32 *= PRIME32_2;
      h32 ^= h32 &gt;&gt; 13;
      h32 *= PRIME32_3;
      h32 ^= h32 &gt;&gt; 16;
      return h32;
  }
  </code></pre>
  
  <p>Run:</p>
  
  <pre><code>$ go build &amp;&amp; ./nocgo #9p native
  134316512
  981225178
  $ go build &amp;&amp; ./nocgo #cgo
  981225178
  981225178
  </code></pre>
  
  <p><strong>TL;DR:</strong></p>
  
  <p>A C function returns the wrong value when used through Go's 6c, same exact C function returns the correct value when called through CGO.</p>
  
  <p>//edit</p>
  
  <p>I got a response on the <a href="https://code.google.com/p/go/issues/detail?id=8454" rel="nofollow">issue</a>, it's not gonna get fixed and the 9p toolchain is going away eventually.</p>
  
  <p>From <strong>mi...@golang.org</strong>:</p>
  
  <blockquote>
    <p>the C compiler will eventually go away. Plan for that, so don't rely
    on it.</p>
    
    <p>Note the Plan 9 C compiler isn't fully ANSI compliant, and we're not
    going to fix bugs in it (because we control both the compiler and its
    input, we will just workaround its bugs).</p>
  </blockquote>