Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I just watched the talk, and I do not entirely agree with what Herb Sutter is saying.</p> <p>If I understand correctly, his argument is as follows:</p> <ol> <li><p><code>[res.on.data.races]/3</code> imposes a requirement on types that are used with the standard library -- non-const member functions must be thread-safe.</p></li> <li><p>Therefore <code>const</code> is equivalent to thread-safe.</p></li> <li><p>And if <code>const</code> is equivalent to thread-safe, the <code>mutable</code> must be equivalent to "trust me, even the non-const members of this variable are thread-safe".</p></li> </ol> <p>In my opinion, all three parts of this argument are flawed (and the second part is critically flawed).</p> <p>The problem with <code>1</code> is that <code>[res.on.data.races]</code> gives requirements for types in the standard library, not types to be used with the standard library. That said, I think it is reasonable (but not entirely clear-cut) to interpret <code>[res.on.data.races]</code> as also giving requirements for types to be used with the standard library, because it would be practically impossible for a library implementation to uphold the requirement to not modify objects through <code>const</code> references if <code>const</code> member functions were able to modify objects.</p> <p>The <em>critical</em> problem with <code>2</code> is that while it is true (if we accept <code>1</code>) that <code>const</code> must imply thread-safe, it is <strong>not</strong> true that thread-safe implies <code>const</code>, and so the two are not equivalent. <code>const</code> still implies "logically immutable", it is just that the scope for "logically immutability" has expanded to require thread-safety.</p> <p>If we take <code>const</code> and thread-safe to be equivalent, we lose the nice feature of <code>const</code> which is that it allows us to easily reason about code by seeing where values can be modified:</p> <pre><code>//`a` is `const` because `const` and thread-safe are equivalent. //Does this function modify a? void foo(std::atomic&lt;int&gt; const&amp; a); </code></pre> <p>Furthermore, the relevant section of <code>[res.on.data.races]</code> talks about "modifies", which can be reasonably interpreted in the more general sense of "changes in an externally observable way", rather than just "changes in a thread-unsafe way".</p> <p>The problem with <code>3</code> is simply that it can only be true if <code>2</code> is true, and <code>2</code> is critically flawed.</p> <hr> <p>So to apply this to your question -- no, you should not make every internally synchronised object <code>mutable</code>.</p> <h3>In C++11, as in C++03, `const` means "logically immutable" and `mutable` means "can change, but the change will not be externally observable". The only difference is that in C++11, "logically immutable" has been expanded to include "thread-safe".</h3> <p>You should reserve <code>mutable</code> for member variables that do not affect the externally visible state of the object. On the other hand (and this is the key point that Herb Sutter makes in his talk), if you have a member that <em>is</em> mutable for some reason, that member <em>must</em> be internally synchronised, otherwise you risk making <code>const</code> not imply thread-safe, and this would cause undefined behaviour with the standard library.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload