On 17/10/17 10:55, Jeffrey Walton wrote: > On Tue, Oct 17, 2017 at 4:12 AM, Andrew Haley <aph@xxxxxxxxxx> wrote: >> On 17/10/17 09:01, Jeffrey Walton wrote: >>> On Tue, Oct 17, 2017 at 3:58 AM, Andrew Haley <aph@xxxxxxxxxx> wrote: >>>> On 17/10/17 08:32, Jeffrey Walton wrote: >>>>> GCC guesses wrong on occasion. It will remove code that has value that >>>>> but does not produce an output because the language does not allow us >>>>> to express it. >>>>> >>>>> The C language lacks what we need to express what we need to do. Its a >>>>> failure of the C (and C++) committees. Its not a GCC failure. >>>> >>>> I disagree. If you want a bunch of asms to execute in a particular >>>> order, add a memory clobber or some dependencies. It's not difficult >>>> once you have the understanding. In this particular case, fixing it >>>> is trivial, and there are many ways to do it. >>> >>> Forgive my ignorance... How does one do it without ASM and in a >>> cross-platform fashion? >> >> I don't understand what you are asking. > > Sorry about that Andrew. I had two or three other use cases in mind > when I wrote that. The use case offered by Brown requires it. > > Sorry again. > > Jeff > I don't what use-cases you have in mind here, but there are a few things you can do with asm that /are/ cross-platform: A basic memory barrier: asm volatile("" ::: "memory") Telling the compiler that it has to have evaluated "x" at this point: #define forceDependency(x) \ asm volatile("" :: "" (x) : ) Telling the compiler that it has to have evaluated "x" at this point, but that "x" might change here so it can't use that knowledge for optimisation: #define forgetCompilerKnowledge(x) \ asm ("" : "+g" (x)) That one is a bit like telling the compiler to treat the previous write to "x" as a volatile write, and the next read like a volatile read, except the compiler can keep x in a register all the time. This macro does the same, but covers a block of memory: #define forgetCompilerBlock(start, size) \ do { typedef struct { char x[size]; } XS; XS *p = (XS *) start; \ asm ("" : "+m" (*p)); \ } while (0); Lots can be done cross-platform in inline asm when the actual assembly part is empty!