3 ms·
> One of my favourite examples is volatile. It's strange that an ancient feature that is almost practically deprecated serves as one of your favourite examples
by jstimpfle 5y ago
> One of my favourite examples is volatile.
It's strange that an ancient feature that is almost practically deprecated serves as one of your favourite examples.
I'm not an expert, but volatile was originally meant to access hardware registers and I believe it did fulfill its purpose at the time. I've never reasearched the official definition of volatile, but it is widely acknowledged that there are few or even no legit uses of it today, because it is not suited to general concurrent programming. This seems like a good SO answer: https://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming https://stackoverflow.com/questions/2484980/why-is-volatile-...
If I understand right, I think you could do multithreaded programming if you restrict to doing message passing of message structures that are marked all volatile. But you can't use much else, because non-volatile data accesses can be reordered around volatile data accesses.
In short, probably just don't use volatile. Use the "modern" memory barriers, those exist in C/C++ just as they exist in Rust.
> Would it mean anything to, for example, integer divide an MMIO fetch by fifteen and write it back? a/= 15; No. So then why make it a type qualifier?
This seems a strange example to me as well. This is equivalent to (a = a / 15). I.e. a volatile read followed by a volatile write. Not defending volatile at all, but I can't see what is so wrong here.
On a different note, attaching too many semantics to types is basically the complaint that I have about most languages. Types are too static and too inexpressive to capture all but the most trivial invariants, so complicated types often require messy and theoretically unnecessary workarounds. I always say, I'd almost like to types capture only the physical shape (sizes, alignment...) of the data, because that is extremely important for optimization and also it doesn't really change. In C, that is almost true, with some exceptions (signed/unsigned, and yes, the crufty volatile)
- jstimpfle 5y agoAddendum: Think about volatile like you think about const. If you use it to declare memory that is in fact different, it totally makes sense. If you do other weird things, it breaks (just like const). This is unlike signed/unsigned storage specifiers which are not really attributes of the memory, and which create some serious complexities that lead to weird situations. But for practical reasons there haven't been any successful attempts to get rid of them. Again, not defending volatile at all. Just saying that it probably made sense at the time at that it is not as ill-conceived as you imply. Volatile is cruft, but certainly does not disqualify the language. Just use modern synchronization primitives instead, like any other reasonable person.