On 07/16/14 15:02, Johannes Pfau via Digitalmars-d wrote: > Am Tue, 15 Jul 2014 19:44:51 +0200 > schrieb Artur Skawina via Digitalmars-d <digitalmars-d@puremagic.com>: > >> Could you show one (concrete) example where using 'volatile' is better >> than my approach? > > I experimented a little more with Volatile!T and I don't think you can > make this example work: > > struct Timer > { > uint control; > uint data; > } > > enum timerA = (Volatile!Timer)* = cast()0xDEADBEAF; > > timerA.control |= 0b1;
Thank you very much for showing actual code. There are many (wrong) assumptions being made in this thread (and the one on the gdc list). Claims like "A is required" or "B is impossible", where A and B are not actually defined and only vaguely described, do not usually lead to a productive dialogue. Concrete examples and code make it possible for the discussion to be about facts and not perceptions. struct Timer { uint control; uint data; } enum timerA = cast(Volatile!(Timer)*)0xDEADBEAF; //enum timerA = volatile_(cast(Timer*)0xDEADBEAF); // works too. void main() { timerA.control |= 0b1; } struct Volatile(PT) { PT raw; auto opDispatch(string M)() @property { return volatile_(mixin(q{&raw.}~M)); } auto opOpAssign(string OP, B)(B b) { auto a = load(*raw); auto r = mixin("a "~OP~" b"); store(*raw, r); return this; } static: T load(T)(ref T v) { asm { "" : "+m" v; } T res = v; asm { "" : "+g" res; } return res; } T store(T)(ref T v, const T a) { asm { "" : : "m" v; } v = a; asm { "" : "+m" v; } return a; } } auto volatile_(A)(A a) { return Volatile!A(a); } // Just for IFTI. when compiled w/ "gdc -O1" results in 0000000000402949 <_Dmain>: 402949: b8 af be ad de mov $0xdeadbeaf,%eax 40294e: 8b 10 mov (%rax),%edx 402950: 83 ca 01 or $0x1,%edx 402953: 89 10 mov %edx,(%rax) 402955: b8 00 00 00 00 mov $0x0,%eax 40295a: c3 retq which is the exact op sequence you'd expect. Doing it as just one R-M-W op would be possible too, but that might not be supported by all HW/platforms. And, yes, gdc inlines it even at -O0, if @inline is used. But at -O0 the generated code is /already/ huge and inefficient, hence not really usable in constrained mem environments. Obviously, this is just a proof of concept and the minimal implementation that can only handle your example. But it's enough to disprove the it-cannot-be-made-to-work-without-c-volatile claim. Are there any other examples of things that cannot be efficiently handled w/o a built-in volatile type qualifier? artur