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

Reply via email to