5

When are const volatile objects necessary in C++?

Note: I do understand the need for pointers to const volatile memory locations, but those don't require the objects themselves to be const or volatile.
I'm asking about objects that are themselves of some const volatile type, for example:

const volatile T obj;

In which situations are these necessary or useful?

Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886
  • 7
    [Memory-mapped hardware status registers](http://en.wikipedia.org/wiki/Memory-mapped_I/O), perhaps. – Igor Tandetnik Aug 14 '13 at 04:33
  • @IgorTandetnik: Wouldn't those be mapped to memory *addresses*? i.e. wouldn't you need to construct pointers to `const volatile`-typed objects, rather than creating `const volatile` objects themselves? – user541686 Aug 14 '13 at 05:09
  • 1
    You can tell the linker where you want certain variables to be placed. When you are working with some special compilers they allow to annotate an address to a variable directly eliminating the need for the pointer introducing the need for `const volatile` objects. – RedX Aug 14 '13 at 05:34
  • @Mehrdad would it be appropriate to tag this with c++11, the meaning has changed somewhat – aaronman Aug 14 '13 at 05:47
  • @aaronman: How has it changed? – user541686 Aug 14 '13 at 05:50
  • @Mehrdad unfortunately my internet is to slow to download the standard right now, but I remember seeing a quote from another answer that said that you should not use volatile for multithreading in c++11 – aaronman Aug 14 '13 at 05:51
  • @aaronman: I don't need a reference to the standard, do you have a link to the answer you saw? I'm not aware of any differences... – user541686 Aug 14 '13 at 05:53
  • This isn't the same as what I saw before but it says a similar thing http://stackoverflow.com/questions/12878344/volatile-in-c11, basically c++ doesn't intend for you to use volatile for concurency – aaronman Aug 14 '13 at 05:53
  • 2
    @aaronman: Yeah but C++03 never intended you to use volatile for concurrency either, right? – user541686 Aug 14 '13 at 05:57
  • @Mehrdad well as I remember the standards quote said that the meaning of volatile is different in a multithreaded context, I presume this is because now c++ has native threading – aaronman Aug 14 '13 at 05:59
  • 2
    @aaronman: Nope, `volatile` never had anything to do with threading, and probably never will. I don't think anything changed in C++11, but if you can show me otherwise I'd love to know. – user541686 Aug 14 '13 at 06:00
  • according to @MatthieuM the meaning did not change but it is more explicitly stated that you should not use it, which is likely what I was thinking of – aaronman Aug 14 '13 at 06:21

1 Answers1

2

The situations are rare where when you actually need volatile in c++. volatile is not useful for multithreaded any more. From this website there are only three portable uses of volatile.

Hans Boehm points out that there are only three portable uses for volatile. I'll summarize them here:

  1. marking a local variable in the scope of a setjmp so that the variable does not rollback after a longjmp.
  2. memory that is modified by an external agent or appears to be because of a screwy memory mapping
  3. signal handler mischief

So basically you want to really only use other features for concurrent programming and save volatile for those rare situations

aaronman
  • 18,343
  • 7
  • 63
  • 78
  • What about Alexandrescu's [cool trick back in 2001](http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766)? TL;DR: class methods can be overloaded by `volatile` to provide nearly transparent tread-safety. – DanielKO Aug 14 '13 at 04:36
  • That is before c++11 the meaning has changed a little – aaronman Aug 14 '13 at 04:39
  • @DanielKO The article I cited totally disagreed with yours, also by a respected developer, I think the problem with volatile is that it is too implementation defined and the standard doesn't specify it well enough. I actually used volatile keyword in a [question](http://stackoverflow.com/questions/18064722/modifying-a-const-variable-with-the-volatile-keyword) I asked and people seemed to think it would not provide consistent behavior – aaronman Aug 14 '13 at 04:45
  • @DanielKO not to mention since your article was written before c++11 there are now many better ways to handle concurrency in c++ than volatile – aaronman Aug 14 '13 at 04:48
  • 1
    Yours was also before C++11, so what? The use of `volatile` on Alexandrescu's article has nothing to do with `volatile` on primitive types. On user-defined types it's just a "free" type qualifier you can use to abuse the type system. The idea is to make the object "volatile", now the user can't reach the thread-unsafe methods (without `volatile`) without explicitly casting the `volatile` away; then provide a way to "un-volatile" that automatically constructs a `unique_lock`. Any attempt to break the thread-safety will be an eyesore (`const_cast`). I don't think those rules changed at all. – DanielKO Aug 14 '13 at 05:06
  • @DanielKO so what, c++ didn't even have native threads before c++11. As for the rest it's clever but as you said yourself it's ***abuse*** and doesn't provide the actual concurrency control – aaronman Aug 14 '13 at 05:11
  • 1
    I said "abuse" in a tongue-in-cheek manner. It's employing an otherwise useless mechanism of the C++ type system to enforce access rights; by default you get the "lowest level" (with `volatile`) and the type system doesn't remove the restrictions until you do so explicitly. Depending on the "level" you get access to different operations; it's not different from "const" methods, other than being less widely spread. It's at least worthy of a "fourth" portable use, even if not directly related to concurrency. – DanielKO Aug 14 '13 at 05:20
  • @DanielKO well the difference is that const is used what i was intended for in addition const has the added bonus of being able to detect if the object is modified, whereas you could mark a function volatile and have it do thread unsafe things – aaronman Aug 14 '13 at 05:23
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/35400/discussion-between-aaronman-and-danielko) – aaronman Aug 14 '13 at 05:41
  • @aaronman: Actually, before or after C++11 changed nothing. Before C++11 `volatile` did not guarantee anything to do with threads because threads were not supported by the Standard and after C++11 `volatile` still does no guarantee anything to do with threads except that now it is explicitly noted in the Standard. `volatile` was created specifically for interaction with hardware registers (back in the C days), one may overload its meaning for other usages (much like one can overload the comma operator) but apart from that it is pretty much useless in day-to-day programming. – Matthieu M. Aug 14 '13 at 06:19
  • @MatthieuM. so probably what I was thinking of is the explicit statement of it's uselessness – aaronman Aug 14 '13 at 06:20
  • @MatthieuM. Also where's the quote I couldn't find it – aaronman Aug 14 '13 at 06:22
  • @MatthieuM.: Was it created specifically for hardware registers, or more generally for any concept which might exist outside the compiler's knowledge, including things like interrupts? The Standard doesn't define any means by which interrupts could exist, but in a lot of systems they do exist, and systems which support interrupts have traditionally implemented `volatile` in a way that ensures that a variable changed in an interrupt will be seen in main-line code and vice versa. – supercat Feb 17 '16 at 19:20
  • @supercat: I cannot recall any mention of interrupt handling in this context, but I did not participate to the discussions (I am not sure I was even born...) so interrupt handling may very well have been considered. – Matthieu M. Feb 17 '16 at 20:06