C++ – Why is const-correctness specific to C++

cconst-correctnessconstants

Disclaimer: I am aware that there are two questions about the usefulness of const-correctness, however, none discussed how const-correctness is necessary in C++ as opposed to other programming languages. Also, I am not satisfied with the answers provided to these questions.

I've used a few programming languages now, and one thing that bugs me in C++ is the notion of const-correctness. There is no such notion in Java, C#, Python, Ruby, Visual Basic, etc., this seems to be very specific to C++.

Before you refer me to the C++ FAQ Lite, I've read it, and it doesn't convince me. Perfectly valid, reliable programs are written in Python all the time, and there is no const keyword or equivalent. In Java and C#, objects can be declared final (or const), but there are no const member functions or const function parameters. If a function doesn't need to modify an object, it can take an interface that only provides read access to the object. That technique can equally be used in C++. On the two real-world C++ systems I've worked on, there was very little use of const anywhere, and everything worked fine. So I'm far from sold on the usefulness of letting const contaminate a codebase.

I am wondering what is it in C++ that makes const necessary, as opposed to other programming languages.

So far, I've seen only one case where const must be used:

#include <iostream>

struct Vector2 {
    int X;
    int Y;
};

void display(/* const */ Vector2& vect) {
    std::cout << vect.X << " " << vect.Y << std::endl;
}

int main() {
    display(Vector2());
}

Compiling this with const commented out is accepted by Visual Studio, but with warning C4239, non-standard extension used. So, if you want the syntactic brevity of passing in temporaries, avoiding copies, and staying standard-compliant, you have to pass by const reference, no way around it. Still, this is more like a quirk than a fundamental reason.

Otherwise, there really is no situation where const has to be used, except when interfacing with other code that uses const. Const seems to me little else than a self-righteous plague that spreads to everything it touches :

The reason that const works in C++ is
because you can cast it away. If you
couldn't cast it away, then your world
would suck. If you declare a method
that takes a const Bla, you could pass
it a non-const Bla. But if it's the
other way around you can't. If you
declare a method that takes a
non-const Bla, you can't pass it a
const Bla. So now you're stuck. So you
gradually need a const version of
everything that isn't const, and you
end up with a shadow world. In C++ you
get away with it, because as with
anything in C++ it is purely optional
whether you want this check or not.
You can just whack the constness away
if you don't like it.

Anders Hejlsberg (C# architect), CLR Design Choices

Best Answer

Const correctness provides two notable advantages to C++ that I can think of, one of which makes it rather unique.

  • It allows pervasive notions of mutable/immutable data without requiring a bunch of interfaces. Individual methods can be annotated as to whether or not they can be run on const objects, and the compiler enforces this. Yes, it can be a hassle sometimes, but if you use it consistently and don't use const_cast you have compiler-checked safety with regards to mutable vs. immutable data.
  • If an object or data item is const, the compiler is free to place it in read-only memory. This can particularly matter in embedded systems. C++ supports this; few other languages do. This also means that, in the general case, you cannot safely cast const away, although in practice you can do so in most environments.

C++ isn't the only language with const correctness or something like it. OCaml and Standard ML have a similar concept with different terminology — almost all data is immutable (const), and when you want something to be mutable you use a different type (a ref type) to accomplish that. So it's just unique to C++ within its neighboring languages.

Finally, coming the other direction: there have been times I have wanted const in Java. final sometimes doesn't go far enough as far as creating plainly immutable data (especially immutable views of mutable data), and don't want to create interfaces. Look at the Unmodifiable collection support in the Java API and the fact that it only checks at run time whether modification is allowed for an example of why const is useful (or at least the interface structure should be deepend to have List and MutableList) — there is no reason that attempting to mutate an immutable structure can't be a compile-type error.