You want
"=m" (*( struct foo { char x[8]; } __attribute__((may_alias)) *)Dest)
Thank you. With your help, that worse-than-useless sample in the docs
is getting closer to something people can actually use.
Except for one last serious problem: This trick only works for very
specific (and very small) sizes of x (something else the existing docs
fail to mention).
On x64: Sizes of 1/2/4/8/16 correctly clobber Dest (and only Dest) as
expected. Trying to use any other values (5, 12, 32, etc) seem to force
a full memory clobber. This is the case REGARDLESS of the actual size
of the underlying structure. For example clobbering 16 bytes of a 12
byte struct only clobbers the 12 bytes of Dest (as expected), but
clobbering 12 bytes of a 12 byte struct performs a full memory clobber.
This presents a problem for general purpose routines like memset, where
the actual size of the block cannot be hardcoded into the struct.
glibc (which uses this trick to avoid using the memory clobber) uses a
size of 0xfffffff. Being larger than 16, this always causes a full
memory clobber, not the "memory constraint" clobber I assume they were
expecting. OTOH, since they don't use may_alias, this is may actually
be a good thing...
While I really like the idea of using memory constraints to avoid all
out memory clobbers, 16 bytes is a pretty small maximum memory block,
and x32 only supports a max of 8. Unless there's some way to use larger
sizes (say SSIZE_MAX), this feature hardly seems worth documenting.
dw