The answer must be more nuanced than that, because it is possible to take a 
nil pointer and construct an unsafe.Pointer from it.  

The reason I am interested in this is (and please don't judge too early) is 
I'm toying around with implementing some atomic primitives.  In particular, 
I would like to play around with with the cmpxchg16b instruction which 
needs 16 byte alignment.   Go does not provide a way to enforce a data 
structure has such alignment, so I am attempting to define a struct that I 
can index into.  (assume 64bit words).  For example, the datastructure I 
want is this:

// alignment of foo is 16
type foo struct {
  uintptr
  unsafe.Pointer
}

But I can't assert this.  The next best thing is to make a struct 2x the 
size, and make a pointer to the first aligned part:

type foo struct {
  [4]uintptr
}

This way I can get an aligned address pointing into the middle of this 
array for using cmpxchg16b.   The problem with this is that if any of the 
interior values are not seen a pointers by the GC.  In order to keep the 
values alive they need to be unsafe.Pointer:

type foo struct {
  [4]unsafe.Pointer
}

Now this is a problem.  There is really only one pointer in here, the other 
value is just some arbitrary bytes.  Since the GC now things the addresses 
are real, it will crash.  What is the correct way to get an aligned struct 
that contains pointers?





On Tuesday, August 21, 2018 at 3:40:55 PM UTC-7, Ian Lance Taylor wrote:
>
> On Tue, Aug 21, 2018 at 1:19 PM, 'Carl Mastrangelo' via golang-nuts 
> <golan...@googlegroups.com <javascript:>> wrote: 
> > 
> > If I create an unsafe.Pointer that points to an invalid memory address, 
> but 
> > I never deference it or otherwise pass it along, what happens to it? 
>
> If you never deference it and never do anything with it, then in 
> practice it most likely gets eliminated by the compiler.  That said: 
>
> > Is it a valid go program to just create such a pointer? 
>
> No.  The only way you could create such a Pointer is by converting 
> from uintptr, or, essentially equivalently, by calling C or assembler 
> code.  The unsafe package docs explain all the cases in which it is 
> permitted to convert a uintptr to an unsafe.Pointer.  Using any other 
> mechanism is invalid.  The permitted mechanisms never produce an 
> unsafe.Pointer that contains an invalid memory address. 
>
> > The main reason I ask is 
> > that I know the GC treats unsafe.Pointer values differently than 
> uintptr. 
> > If the GC were to chase this invalid pointer, it would likely get a 
> > segfault.  This means that either the GC knows not to chase such a 
> pointer, 
> > or it would chase it and gracefully recover. 
>
> In practice, in the current implementation, what will happen is that 
> the GC will attempt to find the object to which the pointer points, 
> will fail, and will crash with a "pointer to unallocated span" error. 
>
> > Additionally, if the unsafe.Pointer is pointing to a incorrectly aligned 
> > address, the GC could potentially misunderstand and try to walk it.  I'm 
> > sure this has been thought of before, but it isn't called out in the 
> docs. 
>
> This isn't an issue with the current implementation.  The current GC 
> doesn't care about the type of the pointer, so pointers have no 
> alignment requirements as far as the GC is concerned.  Every pointer 
> is effectively a *byte for GC purposes. 
>
> Ian 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to