help with g++ and strict aliasing on x86-64

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,
I'm having trouble understanding what I'm doing wrong in the following piece 
of code. 

My OS is Debian GNU/Linux 5.0, compiler is
g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
platform x86-64

The following code results in abort() being called (sorry if it's a bit 
long, but this is the smallest example I could come up with):

  #include <new>
  #include <stdlib.h>
  #include <assert.h>
  #include <stdio.h>
  
  struct Link { Link *next_; }; // __attribute__((__may_alias__));
  struct Foo { void *value; };
  
  struct Alloc {
      Alloc() { head_ = NULL; }    
      ~Alloc() {}
  
      void *allocate()
      {
          static int cnt = 0;
          if (head_ == NULL) {
              if (cnt++) { abort(); }
  
              Link *mem = static_cast<Link *>(malloc(sizeof(Link) * 3));
              head_ = new (mem) Link;
              Link *last = head_ + 2;
              for (Link *p = head_; p < last; ++p) {
                  Link *next = new (p+1) Link;
                  p->next_ = next;
              }
              last->next_ = NULL;
          }
          Link *p = head_;
          head_ = p->next_;
          p->~Link();
          return static_cast<void *>(p);
      }
          
      Link *head_;
  };
  
  struct FooAlloc {
      Foo *alloc() { return new (p_.allocate()) Foo(); }
      Alloc p_; 
  };
  
  int main()
  {
      if (sizeof(Foo) != sizeof(Link)) { abort(); }
      printf("here\n"); fflush(stdout);
      
      FooAlloc pool;
      Foo *e = pool.alloc();
      if (e) {
          printf("e\n"); fflush(stdout);
      }
      e = pool.alloc();
      return 0;
  }


If I uncomment the "may_alias" attribute, everything works. But I don't 
quite understand why "may_alias" is needed here. Could somebody help please? 
My understanding is that, since in Alloc::allocate() I'm calling the 
destructor of p before returning a pointer to the memory in which it is 
allocated, and in FooAllo::alloc() I'm constructing a new object in that 
memory area, aliasing should not be an issue. I'm pretty sure I'm missing 
something, but I can't see it... If somebody could help me, that would be 
very much appreciated. FWIW, If I use gcc 4.3 on the same machine
(to be precise: gcc-4.3 (Debian 4.3.2-1.1) 4.3.2) abort() is not called.


Thanks in advance,
Alberto



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux