Live data from Hacker News

Ways to break your systems code using volatile (2010)

blog.regehr.org

71–77 of 77 posts

Re: Ways to break your systems code using volatile (2010)

#71

This should say 2010. I believe much of it is out of date, as C11 does have a memory model, and does provide both atomics and barriers. Many, if not most, uses of volatile should probably be replaced by atomics. https://en.cppreference.com/w/c/atomic

Many projects are stuck in C99, or even C89...

And many projects aren't. It is still better to label a title correctly.

Re: Ways to break your systems code using volatile (2010)

#72
post #67

Earlier quoted context omitted.

That is a reasonable heuristic but your statement is not technically correct. E.g. you need volatile around setjmp/longjmp and that has nothing to do with IO.

And if your GC doesn't dump the registers. Only with volatile you can keep all locals on the stack. And yes, that's not stupid. It's actually faster than all the register "optimizations" for practical use cases in fast VM's. Register saving across calls and at the GC is much more expensive. mem2reg is an antipattern mostly

GC (of the kind where an external context walks other thread machine stacks) definitely falls under implementation-defined :-).

Re: Ways to break your systems code using volatile (2010)

#73
post #13

Err...volatile just tells the compiler not to cache the value in a register, that's it. If you don't understand volatile you really, really are not the kind of programmer who should even think about using it.

This is my understanding of volatile as well: volatile just forces read/write to memory. What a read/write to memory entails is a different story. What happens with no volatile is again another story. If my understanding is wrong, someone please enlighten me.

"Forcing read/write to memory" is very different from "not caching the value in a register". Optimizations can involve not just caching values in registers, but also reordering operations, calculating things at compile-time and so on.

For a trivial example, see this code:

    int f() {
        int sum = 0;
        for (int i = 0; i 
As you can see from [1], a smart compiler will calculate the sum at compile time and make the function simply return the resulting number (i.e., no loop is generated).

If you make "sum" volatile, the compiler is forced to do the loop[2].

[1] https://godbolt.org/z/3sX5mU

[2] https://godbolt.org/z/F5CiDJ

Re: Ways to break your systems code using volatile (2010)

#75
post #65
post #23

That note at the end about Linux is missing a link to the Documentation/volatile-considered-harmful.txt document. Basically, don't use volatile. Here, with your choice of formatting: https://github.com/torvalds/linux/blob/master/Documentation/... https://www.mjmwired.net/kernel/Documentation/volatile-consi... https://www.kernel.org/doc/html/latest/process/volatile-cons...

Neat how inline assembly is one of the valid use cases. I'm given to understand that essential parts of the Linux kernel can't actually be implemented in pure C and that some assembly is required.

Isn't that the case for most (all?) operating systems?

Re: Ways to break your systems code using volatile (2010)

#76

I've never had to use volatile in code. This was all very interesting! For issue #5, a possible solution not mentioned could be to write inline assembly, no? It would keep the array non-volatile and should be portable.

Inline assembly is basically the definition of non-portable.

Re: Ways to break your systems code using volatile (2010)

#77

You really should just use volatile for device drivers when accessing IO space with side-effects. Do not use volatile to build your own synchronization primitives.

What do you think about signal handlers? Atomics may be implemented with locks, which makes them unsuitable for signal handlers. The only guaranteed lock-free type is `std::atomic_flag` which is not very useful. `volatile sig_atomic_t` still seems like the better choice for signals.

Indeed, "volatile sig_atomic_t" is the recommended official C way to change a flag from a signal handler.
Post reply on HN