<div dir="ltr">On Thu, Feb 14, 2013 at 11:34 AM, Brian Cole <span dir="ltr"><<a href="mailto:coleb@eyesopen.com" target="_blank">coleb@eyesopen.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Does clang have a compiler warning for when code could be breaking deep const-ness? </blockquote><div><br></div><div style>
Nope.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I know this is legal in C++, but it is often undesirable, especially in light of const now implying thread safety in most libraries.</blockquote>
<div><br></div><div style>Even in the latter case it's hard to know which parts of an object are part of its identity. Unless there are some particularly accurate heuristics we could use to guess whether an object is part of the object identity of some other object I doubt we could add such a warning.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> We just chased a thread safety bug down to a problem like the following:<br>
<br>
struct Foo<br>
{<br>
  void DoSomething();<br>
};<br>
<br>
class Bar<br>
{<br>
  Foo *foo;<br>
  void DoConstSomething() const { foo->DoSomething(); }<br>
};<br>
<br>
If clang doesn't have this warning, it would be extremely useful to have as we migrate to a concurrent world. I would propose that to work around the warning the user could do one of the two following things:<br>
<br>
class Bar<br>
{<br>
  mutable Foo *foo;<br></blockquote><div><br></div><div style>Except this has another meaning - it means that 'foo' is changeable under 'const', not that the thing foo points to is/isn't.</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
// OR the following const_cast<br>
  void DoConstSomething() const { const_cast<Foo *>(foo)->DoSomething(); }<br>
};<br>
<br>
What makes this even trickier is that the std smart pointer classes allow you to do the same thing. I don't know if clang could also warn about these as well, but having the former would be a good first step in the right direction.</blockquote>
<div><br></div><div style>At least with std::unique_ptr you know the object isn't shared so the chance that it forms part of the object identity of the enclosing object is a bit higher, but probably still not good enough I'd wager.<br>
<br>I've seen people attempt to solve this with a library solution:<br><br>deep_const_ptr<T> x;<br><br>where op* and op-> return const/non-const references as appropriate.<br><br>This is probably more likely to be the way to solve your problem - along with some kind of stylistic guideline in your codebase that members that are pointers to portions of the value of an object should use this wrapper (& that way you can see when you read the code which members are part of the object identity and which ones are not)</div>
</div></div></div>