I hear that const means thread-safe in C++11. Is that true?
Does that mean const is now the equivalent of Java‘s synchronized?
Are they running out of keywords?
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
It is somewhat true…
This is what the Standard Language has to say on thread-safety:
which is nothing else than the sufficient condition for a data race to occur:
The Standard Library builds on that, going a bit further:
which in simple words says that it expects operations on
constobjects to be thread-safe. This means that the Standard Library won’t introduce a data race as long as operations onconstobjects of your own types eitherIf this expectation does not hold for one of your types, then using it directly or indirectly together with any component of the Standard Library may result in a data race. In conclusion,
constdoes mean thread-safe from the Standard Library point of view. It is important to note that this is merely a contract and it won’t be enforced by the compiler, if you break it you get undefined behavior and you are on your own. Whetherconstis present or not will not affect code generation –at least not in respect to data races–.No. Not at all…
Consider the following overly simplified class representing a rectangle:
The member-function
areais thread-safe; not because itsconst, but because it consist entirely of read operations. There are no writes involved, and at least one write involved is necessary for a data race to occur. That means that you can callareafrom as many threads as you want and you will get correct results all the time.Note that this doesn’t mean that
rectis thread-safe. In fact, its easy to see how if a call toareawere to happen at the same time that a call toset_sizeon a givenrect, thenareacould end up computing its result based on an old width and a new height (or even on garbled values).But that is alright,
rectisn’tconstso its not even expected to be thread-safe after all. An object declaredconst rect, on the other hand, would be thread-safe since no writes are possible (and if you are consideringconst_cast-ing something originally declaredconstthen you get undefined-behavior and that’s it).Let’s assume –for the sake of argument– that multiplication operations are extremely costly and we better avoid them when possible. We could compute the area only if it is requested, and then cache it in case it is requested again in the future:
[If this example seems too artificial, you could mentally replace
intby a very large dynamically allocated integer which is inherently non thread-safe and for which multiplications are extremely costly.]The member-function
areais no longer thread-safe, it is doing writes now and is not internally synchronized. Is it a problem? The call toareamay happen as part of a copy-constructor of another object, such constructor could have been called by some operation on a standard container, and at that point the standard library expects this operation to behave as a read in regard to data races. But we are doing writes!As soon as we put a
rectin a standard container –directly or indirectly– we are entering a contract with the Standard Library. To keep doing writes in aconstfunction while still honoring that contract, we need to internally synchronize those writes:Note that we made the
areafunction thread-safe, but therectstill isn’t thread-safe. A call toareahappening at the same time that a call toset_sizemay still end up computing the wrong value, since the assignments towidthandheightare not protected by the mutex.If we really wanted a thread-safe
rect, we would use a synchronization primitive to protect the non-thread-saferect.Yes, they are. They have been running out of keywords since day one.
Source: You don’t know
constandmutable– Herb Sutter