3 ms·
They did, elsewhere: https://news.ycombinator.com/item?id=36068685 https://news.ycombinator.com/item?id=36068685 Even if volatile was absolutely all you needed
by reitzensteinm 3y ago
They did, elsewhere: https://news.ycombinator.com/item?id=36068685 https://news.ycombinator.com/item?id=36068685
Even if volatile was absolutely all you needed, why would the committee build a memory model with a nice API and then force you to sprinkle in volatile? It makes absolutely no sense.
- kazinator 3y agoVolatile is what you would use when you don't care about the DEC Alpha, and ignore the API. When using the API, you wouldn't require volatile. You can build yourself an access API if you have volatile. E.g. #define volatile_lvalue(TYPE, LOC) (*(volatile TYPE *) &(LOC)) With typeof or _Generic, we can eliminate the TYPE argument. Then you can do: if (volatile_lvalue(int, i) == 3) { y = x[i]; // don't care if i replaced with 3 here } The user of volatile_lvalue doesn't have to declare anything volatile.
- gpderetta 3y agoThat's the crux of the matter: if i is replaced with 3 on the second line, what do you think prevents an ARM CPU from hoisting the x[3] above the i load first line? In practice the volatile cast might prevent current GCCs from performing constant propagation, so this exact code sequence might work, but it is extremely fragile and can break for some variations: if (int i2 = volatile_lvalue(int, i); i2 == 3) { y = x[i2]; // i2 is replaced, no data dependency } or if (volatile_lvalue(int, i)) { y = x[i-i]; // data dependency becomes a control dependency } You also have to be careful to what you do with y and with any value derived form it. As currently there is no way to efficiently implement consume you have to do with what you have, so for example the Linux kernel does use volatile casts and compilation barriers to implement LOAD_ONCE, but then has a large manual that documents what operations are currently considered safe and what are known to break. That's hardly a specification that can be put in a standard and you can't really can reason about the semantics of it. Linus himself has considered multiple time if it is worth the hassle and whether the kernel should just switch to acquire everywhere now that arm and power have relevant cheap barriers.
- kazinator 3y agoAh, for that problem, I'd prefer to have read_barrier() and write_barrier() type primitives that take no arguments.