I find this an inappropriate answer. Yes, they need care, but it should at
least be possible to figure out how to use them from reading documentation
(carefully). I tend to agree, that neither the spec nor the documentation
of the atomic package is particularly helpful about these questions; at
least I fail to read them in a way that unambiguously answers them.
Without an authoritative and unambiguous description about what is
guaranteed it is impossible to implement this robustly and if the spec
isn't sufficiently unambiguous, it's natural to ask questions. Saying "you
are not supposed to use them, unless you know how to use them" is, in
context of all of this, just shutting people out.

FWIW, I read the spec
<https://golang.org/ref/spec#Size_and_alignment_guarantees>, Dave Cheney's blog
post <https://dave.cheney.net/2015/10/09/padding-is-hard> about padding,
the therein referenced #599 <https://golang.org/issue/599> and the
atomic-documentation <https://godoc.org/sync/atomic#pkg-note-bug>, I find
the whole situation still somewhat confusing. To try to interpret all of
this and answer OPs question:

I believe, that fields do not necessarily need to be properly aligned
(explaining 599). However, *structs* have a necessary alignment, as
required by their fields. So, if you do
type S struct {
    A uint32
    B uint64
}
then there is no guarantee, that B is 64-bit aligned. The spec tells us,
that unsafe.Alignof(s.A) will return 4 ("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", s.A is of type uint32 and such a variable has alignment 4),
unsafe.Alignof(s.B) will return 8 and thus, unsafe.Alignof(s) will return 8
("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").

This means, that the compiler needs to align S on 64 bits. Now, #599 tells
us, that on some archs s.B will *not* be 64 bit aligned. This is in
accordance with the spec though, as confusing as that seems; the spec says
only, how *a variable of the same type *as s.B must be aligned, not how s.B
itself must be aligned (this is, where the confusion stems from). So a
compiler might or might not insert padding.

What all of this means, I believe, is
* The atomic-documentation (maybe?) tells you, that the first field in a
struct can be relied upon to be aligned. It says "the first word", though,
and from what I can tell, there is nothing preventing a compiler to insert
arbitrary padding at the beginning of a struct, technically speaking.
* Thus you can guarantee that s.B is 8-byte aligned, by switching the
fields around
* Thus, your question about the embedding of expvar.Float seems to be "yes,
it's safe", as the struct itself must be 64-bit aligned, even if embedded,
and the 64-bit field is the only one contained
* Your question about WaitGroup seems to be answerable by referring to the
fact, that *technically *the noCopy field could misalign the data. But I
tend to agree, that this reading would allow us to use a uint64, if we
switch noCopy and state. Dave Cheney's blog post about padding wouldn't
create technical problems here, because noCopy isn't the last field, thus
gets no storage allocated…
* Also, all of that reading seems to suggest that there really is no
reliable, guaranteed way, to have multiple fields with a guaranteed
alignment. So, if you need multiple variables to be accessed by atomics,
you are out of luck.

Now, all of that being said, my reading could also be wrong. In any case,
in my opinion, the fact that there is considerable guesswork involved,
seems to suggest, that the spec is either ambiguous or insufficient to
actually allow safe usage of atomics. It would be nice, if it could be a
bit more explicit about what happens to fields. I understand, though, that
we don't want to restrict too much the flexibility of a compiler to insert
padding. But maybe a guarantee about the first field (not "word", what does
that even mean?) of a struct being aligned, even the first fields (plural),
if they all have the same alignment as the struct, would be clear enough
*and* compatible with what compilers are already doing.


On Sat, Feb 4, 2017 at 3:31 PM, Lars Seipel <lars.sei...@gmail.com> wrote:

> On Sat, Feb 04, 2017 at 01:30:49AM -0800, T L wrote:
> > Get it. This is quite bug prone to write programs on 64bit OSes and the
> > programs are expected to run on 32bit OSes too.
>
> Well, there's a reason the sync/atomic package docs have this statement
> right at the top:
>
> > These functions require great care to be used correctly. Except for
> special,
> > low-level applications, synchronization is better done with channels or
> the
> > facilities of the sync package.
>
> --
> 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.
>

-- 
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