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.