DIP62: Volatile type qualifier for unoptimizable variables in embedded programming

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 16 12:20:00 PDT 2014


On 7/16/2014 5:59 AM, Johannes Pfau wrote:
> And how do you implement this with a wrapper? This is common in C/C++:
>
> struct Timer
> {
>      uint control;
>      uint data;
> }
>
> enum timerA = (Volatile!Timer)* = cast()oxDEADBEAF;
>
> timerA.control |= 0b1;

   auto timerA = VolatileStruct!Timer(0xDEADBEAF);
   timerA.control |= 1;

i.e. with introspection, the template can automatically generate the 
getters/setters and operator overloads.


> The more I think about it the more corner cases appear. After all
> implementing this in the library is much more complex than a type
> qualifier. Some of the complexity is already implemented (alias
> this, ...) so there's less changes in DMD. But any bug in alias this,
> templates, etc will immediately leak into Volatile!T.

It's true that VolatileStruct will be more complex than the average template. 
But it's quite doable, and the user won't see that complexity.


>> The point is it is not perfectly safe. There is no definition, and
>> certainly no portable definition, as to how many read/write cycles
>> such an operation entails. That's what I meant, and DIP62 says pretty
>> much said the same thing. Please allow me to quote:
>
> In cases where you use |= the exact number of accesses usually does not
> matter. What matters is that there's at least one access and that it's
> not reordered with other reads/writes to volatile.

I understand, but the pedantic in me notes the word "usually".


> For example |= is used on control registers. But I don't care if I
> read/set the bit twice or once, I just doesn't matter.

I understand that it usually does not matter. But sometimes it does. It should 
be under user control rather than "whatever the compiler does" which can change 
with optimization settings. C compiler semantics for volatile are 
"implementation defined", which pretty much means "random".


> And what does peek/poke guarantee in that case?

It guarantees semantics for (A op= B) to be (A = A op B).


> One important point is that this must be as effective as
> c+volatile (in terms of code size and execution cycles). This is an
> important aspect for embedded programming

I fully agree.


> and it'll take ages and many
> language changes to make a type wrapper as efficient.

This is unduly pessimistic.


> If it's even possible at all.

I see no reason to quit before we start.


>> That is not what I'm saying at all. Please do not conflate
>> disagreement about the best way to achieve a goal with disagreement
>> about the goal.
>
> So you do think peek/poke is a better solution than DIP62? Then you
> have to explain this. All arguments so far have been it's too
> complex in the compiler implementation, but never that peek/poke is a
> better way to achieve that goal of accessing volatile memory.
>
> In the end it's a judgement call between complexity and more
> convenience for embedded programming and it's absolutely your decision.
> But as long as I'm not convinced that peek/poke is a _better_ solution
> I'll think that embedded programming is not important enough for you to
> implement the _best_ solution, as it causes some implementation
> complexity. And this in the end means it's of lower priority to you
> than keeping some complexity out of the compiler.

I think it unfair to impute motives when I've specifically said otherwise.


>> I understand that you and others put a lot of work into DIP62. As I
>> said before, it's a very nice example of a well-done DIP.
>>
>
> That's not the point.

I think it is fair to acknowledge the good work you've done.


> If I were convinced there's a better solution,
> I'd be glad to accept it. But I'm not convinced at all, the only
> argument against DIP62 so far was complexity.

Complexity is not a minor issue. Complexity means time and bugs. I am all too 
familiar with how volatile in C++ has been costly in a lot of effort, bugs, 
specification, and code that had no use for volatile, yet had to account for it.

BTW, testing of "volatile" behavior in the compiler is problematic as there just 
doesn't seem to be a reasonable way to do it. This engenders a regular risk of 
compiler breakage, and shows up to the end user as erratic behavior and lots of 
cursing at the compiler vendor.


More information about the Digitalmars-d mailing list