Ian, thanks for the answers.

But I still not very confirm on many points.

Up to now, there are two places mention the alignments in Go.

The first is in the end of Go spec:
 
Size and alignment guarantees 

For the numeric types <https://golang.org/ref/spec#Numeric_types>, the 
following sizes are guaranteed: 

type                                 size in bytes

byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16

The following minimal alignment properties are guaranteed: 

   1. For a variable x of any type: unsafe.Alignof(x) is at least 1. 
   2. For a variable x of struct type: unsafe.Alignof(x) is the largest of 
   all the values unsafe.Alignof(x.f) for each field f of x, but at least 
   1. 
   3. For a variable x of array type: unsafe.Alignof(x) is the same as 
   unsafe.Alignof(x[0]), but at least 1. 

A struct or array type has size zero if it contains no fields (or elements, 
respectively) that have a size greater than zero. Two distinct zero-size 
variables may have the same address in memory. 


The second is at the end of sync/atomic docs:


On x86-32, the 64-bit functions use instructions unavailable before the 
Pentium MMX. 

On non-Linux ARM, the 64-bit functions use instructions unavailable before 
the ARMv6k core. 

On both ARM and x86-32, it is the caller's responsibility to arrange for 
64-bit alignment of 64-bit words accessed atomically. The first word in a 
global variable or in an allocated struct or slice can be relied upon to be 
64-bit aligned. 


I feel the two are not enough to remove all my confusions.

So could you help me remove the following confusions:


1. What does the "allocated struct or slice" mean?


Currently, I think it means the structs or slices created by new, or the 
structs or slices escape to heap.

Is my understanding right?


2. Are local 8-bytes variables 64bit aligned on 32bit OSes?


I found there are many usages of the 64bit functions of atomic package 
being used on local 8-bytes variables in go source.

So I think the answer is yes. Right?


3. Are expvar.Int and expvar.Float safe to be embedded in other structs on 
32bit OSes?


I think the answer is no. Is my opinion right?





On Sunday, February 5, 2017 at 1:38:21 PM UTC+8, Ian Lance Taylor wrote:
>
> On Sat, Feb 4, 2017 at 2:38 PM, Axel Wagner 
> <axel.wa...@googlemail.com <javascript:>> wrote: 
> > On Sat, Feb 4, 2017 at 11:13 PM, Ian Lance Taylor <ia...@golang.org 
> <javascript:>> wrote: 
> >> 
> >> The spec does not say that unsafe.Alignof(s.B) will return 8.  In 
> >> fact, on 32-bit targets, with the gc toolchain, it will return 4. 
> > 
> > 
> > To me, that seems to contradict the combination of "The functions 
> Alignof 
> > and Sizeof take an expression x of any type and return the alignment or 
> > size, respectively, of a hypothetical variable v as if v was declared 
> via 
> > var v = x" and the table at the very bottom, saying an uint64 has 
> Alignof 8. 
> > The latter seems to strongly imply that a "var v = s.B" must be 8-byte 
> > aligned, as v is a variable (even an allocated one; one of the few 
> mentions 
> > of "allocate" in the spec :) ) of type uint64. Then, the former would 
> imply 
> > that the same happens to s.B, as that is how the function is defined. 
>
> The table at the very bottom is only type sizes, not type alignments. 
>
>
> >> That is sufficient to ensure that your code works correctly.  It does 
> >> mean that certain kinds of operations don't work.  sync.WaitGroup 
> >> plays the games it does to avoid introducing an extra allocation. 
> > 
> > 
> > I don't understand. Where is the extra allocation, if you where to 
> change 
> > state to be an uint64 and just dereference it, instead of using 
> > unsafe.Pointer casting in state()? 
> > 
> > Am I understanding it correctly that you are saying a) yes, fields like, 
> say 
> > expvar.Float can not be embedded, unless you take special care 
> (recursively) 
> > of having it aligned and b) the only safe way to use atomic with fields 
> > would be, to put a pointer in and allocate with new (and that's the 
> "extra 
> > allocation" WaitGroup is trying to avoid?). 
> > 
> > I would find that situation understandable, but also pretty unfortunate. 
> It 
> > seems very easy to make a mistake that way (embedding a type, not 
> knowing 
> > that it relies on atomics). It also means, it's harder to make the zero 
> > value of a struct useful; while having a uint64 intiialized to zero is a 
> > perfectly fine default for a lot of cases, needing to allocate it with 
> new 
> > requires a constructor. 
>
> Yes. 
>
>
> > I would hope we could at least a) recommend that (and maybe the 
> WaitGroup 
> > trick) as "the" ways to use atomic somehow and b) have some kind of 
> check to 
> > detect misuse. The memory layout of all structs is statically known, so 
> it 
> > should be theoretically possible to detect usages of 
> atomic.AddUint64(&s.f) 
> > (or the like) with a misaligned field, no? 
>
> Sounds like a good cmd/vet check. 
>
> 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