The issue with languages like C++ is, that you can follow better
programming practices, but the compiler doesn't support you in the
verification and accordingly you can't trust that easily your code,
which complicates the reasoning about a system a lot.
Having properties like immutability and pureness in your language
makes it lot easier to trust your code and to reason about it.
Clojure doesn't give you immutability guarantees, it just makes it harder to chose otherwise, but on the other hand calling a Java method on some object is just one special form away. I'm not saying Clojure does the wrong thing here btw, but this thing you're talking about is a fallacy, unless you're working in Haskell and even there you could find ways to screw things up by interacting with the outside world, which isn't immutable.
"I'm not saying Clojure does the wrong thing here btw, but this thing you're talking about is a fallacy ..."
Please, read exactly.
"... unless you're working in Haskell and even there you could find ways
to screw things up by interacting with the outside world, which isn't
immutable."
The whole point is, that you're able to express immutability and pureness
in a language like Haskell _AND_ have a compiler which can verify it.
You will never be able to prohibit any screwing, but you can make it a lot
harder to screw something.
That your code uses neither is trivially verified with grep. Are you saying your issues would be solved if someone added a ten-line patch to gcc for -Wconst-cast (that provided a waning, obiously upgradable to an error, if you used const_cast; as in, similar to -Wold-style-cast)?
You really can't express immutability and pureness in C++, because you can
still modify global variables and do any kind of IO everywhere, regardless
of const.
const_cast isn't the big issue, because there's also unsafePerformIO in
Haskell. For both you could say, that they shouldn't be used, that it's
bad programming practice to use them.
The point is, even if you follow good programming practices in C++, you
can't express them and your compiler can't help you in the verification,
if you're really following them.
That doesn't might seem like a big thing, it's also not related to your
smartness, because it mostly depends on the size and complexity of your
system.
If you are arguing that you don't have immutability by default across all values, that is a very different point that I think you need to provide more clarity for... I mean, of course you can modify state that has nothing to do with the variables that are marked const "regardless of const": that is sufficiently obvious as to be a useless comment. However, you really can mark values as const in C++ and allow the compiler to verify that you aren't doing anything non-epic to defeat it. Yes: you can still accidentally or purposefully access the memory via a random hand-calculated pointer, but we can actually harden the compiler (not the language: no changes there required) against that as well by just keeping you from using pointer arithmetic (really, that's a feature that tends to only be used in restricted contexts anyway).
Having properties like immutability and pureness in your language makes it lot easier to trust your code and to reason about it.