7 ms·
Volatile is Evil
- alextingle 16y agoIt is very annoying that 'volatile' means different things in different languages. Inexcusable that Microsoft should unilaterally change the meaning of 'volatile' in their C++ compiler, adding yet another #ifdef into everyone's code.
- Roritharr 16y agowhen talking about different things in different languages I always shudder and have to think about "static", going from java to c++ this was horrible
- iamaleksey 16y ago'static' in C is the worst - it has 2 different meanings within the same language. Does anyone know the reason for this confusing design decision?
- dfox 16y agoReason for this is that static actually does exactly same thing in both cases: defines global variable without externally accessible name and makes it accessible in enclosing scope. (exact standarteese being "internal linkange with static storage duration")
- alextgordon 16y agoIt's actually quite remarkable the number of places a single keyword can be used. We have * Static functions in C * Static variables in C * Static members in C++ * Static instance variables in Java * Static methods in Java The strange combination of C++'s namespaces and static begets static members, which almost make sense in context. But then Java stole the syntax and not the rest of the language (thank god), leading to its strange, almost contradictory usage.
- pivo 16y agoIn Java there are also static inner classes and static initializers (static code blocks that initialize static data)
- dfox 16y agoBoth C and C++ defines volatile as something like "Access to volatile objects are evaluated strictly according to the rules of the abstract machine." (exact wording from some old draft of C++0x I have here) with C explicitly noting that "What constitutes an access to an object that has volatile-qualified type is implementation-defined." (ISO 9899 6.7.3.6). So there is not many to say about what volatile means without knowing exact implementation (and implementation should document what volatile exactly means). I don't see what Microsoft could do to unilaterally change meaning of something that is almost completely implementation-defined.
- JoachimSchipper 16y agoI'm not so sure that your reading of the standard is correct. From n1256.pdf, the essentially unchanged and freely available draft of the C99 standard: (5.1.2.3.2): Accessing a volatile object, ..., or calling a function that does any of those operations are all side effects... (5.1.2.3.3): In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object). It does not look like this allows an implementation complete freedom in deciding what constitutes an "access". In fact, I'm pretty certain that 'volatile int i; i;' is required to access i exactly once. (There are plenty of optimizer bugs in this area, but these are bugs.) (Note that the above has nothing to do with threads and everything with memory-mapped devices. Perhaps you were thinking of threads? These are not part of the C standard, though.)
- dfox 16y ago(6.7.3.6): What constitutes an access to an object that has volatile-qualified type is implementation-defined. That seems to me like giving 'complete freedom in deciding what constitutes an "access"'. Or almost. Actually, chapter 4.10 of GCC 4.4 manual documents how is this defined by GCC and explicitly states, that discarding result of read of volatile object does not always cause access to such object.
- alextingle 16y ago
- kikibobo69 16y agoJava defines it in a very useful way. It's identical to an AtomicReference, but without any test&set semantics. Anything other than that seems pretty dangerous. Personally I find the issue with volatile is that it's quite subtle unless you're looking at the declaration. I tend to use AtomicReference even if I don't need test&set, unless it's extremely performance critical, but it almost never is. The inner loop variables don't need to be volatile.
- Symmetry 16y agoFrom "Nine ways to break your systems code using volatile" at http://blog.regehr.org/archives/28 http://blog.regehr.org/archives/28 "You can find various rants, screeds, and diatribes against volatile on Linux mailing lists and web pages. These are largely correct, but you have to keep in mind that: Linux often runs on out-of-order multicores where volatile by itself is nearly useless. The Linux kernel provides a rich collection of functions for synchronization and hardware access that, properly used, eliminate almost all need for volatile in regular kernel code. If you are writing code for an in-order embedded processor and have little or no infrastructure besides the C compiler, you may need to lean more heavily on volatile."
- dkersten 16y ago"It used to have a very specific purpose - to enure memory operations with external side-effects did not get reordered" Prevent reordering? I thought thats what memory fences are for. -- I admit to having a (single) volatile varibale in my C++ codebase, used similarly to the pseudocode below: volatile global bool flag = false; // [1] thread1 { while (whatever) { do stuff } flag = true; thread2.wait(); } thread2 { while (!flag) { // [2] do stuff } } [1] The variable itself is global, because I read someplace that the C/C++ standard does not allow local volatile variables to be passed to other threads. Logically, this makes sense, if a local goes out of scope before the second thread is finished with it. In my code this cannot happen, but I still make it global anyway. [2] The important part is that this read is very fast unless the flag has been set (at which point I no longer care about efficiency). I don't mind if this is unsynchronized - if the loop runs an extra few iterations, that is perfectly fine, as long as the flag change is seen eventually (realistically, within a few iterations of the loop). I know that volatile only makes sure the compiler doesn't cache the value in registers and does not mean that the value will be synced or flushed or otherwise ensure it is visible by the other thread. On x86 at least, it will be, eventually. My logic for using it in this way is as follows: I do not care about synhronization - if the reader sees a stale value of flag, that is fine, as long as it sees the real value at some point in the future. I use volatile, because otherwise the compiler could simply cache the flag in a register completely isolated form the other thread. I also don't mind if the read is reordered, as long as it is within the loop and the value is used as the loop temrination condition (from what I read on the Intel site[3], the above code guarantees this - but the read may be reordered to appear elsewhere WITHIN the loop instead. This is perfectly fine in my case). I do need the write to appear AFTER the loop in thread1 and before the wait, however - again, afaik I don't need to do anything here, or should I put an sfence before the flag=true to be safe? Since I don't care about performance in the flag is true case, I don't mind adding memory fences in this case. I wonder if somebody can let me know if my logic is off here (though it works on x86 and x86-64 and, accoridng to something I read on the Intel site[3], is a reasonable approach - however, I may port to ARM at some stage, in which case I will need to re-evaluate this code). My aim here is that the reader always reads the flag from the processor cache, so that its fast, but when the writer sets the flag, the cache is synced over the core interconnect and the second thread will, at some stage, see the new value. Is this approach reasonable? Is it safe? I believe it is, but.. [3] http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ http://software.intel.com/en-us/blogs/2007/11/30/volatile-al... Tenth comment down, posted by "spud".
- redpill27 16y agoThis article describes how a volatile variable can be useful when dealing with excess floating-point precision: http://blog.jagpdf.org/2009/07/avoiding-excess-floating-point_17.html http://blog.jagpdf.org/2009/07/avoiding-excess-floating-poin...
- deleted 16y ago[deleted]