
Why Const Sucks - jesperht
http://jmdavisprog.com/articles/why-const-sucks.html
======
abacate
> D's const is also transitive, meaning that if something is const, then
> everything it contains or refers to is also const. If D code has the
> equivalent of const vector<T*>, then not only is the container treated as
> const, but the elements are as well.

And that is not necessarily what the programmer wants.

There are a number of uses for a constant vector and non-const objects. Adding
"const" in front of "T" should make everything constant, but just assuming
everything is constant does not allow one to have non-const objects.

Unless there is a way to override this, it looks like a severe limitation in
the language.

------
signa11
> All of this means that const actually provides zero guarantees about an
> object not being mutated (and even in the case where the object is directly
> constructed as const, that just means that it's undefined behavior when the
> object is mutated, not that the compiler actually protects against it being
> mutated).

if this is the only reason why author thinks that const is a problem, then it
is all good. you can do the same thing in C as well. and ofcourse, if you do
that, and break things, you get to hold all the pieces as well :)

probably a 'constexpr' semantics is what the author might be looking for ?

arne-mertz article on mutable, available here: [https://arne-
mertz.de/2017/10/mutable/](https://arne-mertz.de/2017/10/mutable/), which
imho, is another side of the const-coin, is quite good as well.

edit-001 : slight change.

~~~
gorgonical
I agree. Even extremely safe languages like Ada, which have found most of
their use in safety-critical situations like in plane avionics and medical
equipment, allow the programmer to do "unchecked conversions," the equivalent
of a static_cast.

It would actually be insane for const to forbid the programmer from doing any
of these things. A certain amount of a language and its features is to protect
your program from other programmers, to communicate your idea and vision about
the code. In that way, const is amazingly useful.

~~~
signa11
> A certain amount of a language and its features is to protect your program
> from other programmers, to communicate your idea and vision about the code.

indeed ! language is about telling others (and yourself) about ideas that you
want to express. c and c++ seems to be more suited for 'consenting adults' (oh
dear) than anything else :)

------
kazinator
> _Now, Java also added a number of nice things that C++ didn 't have - such
> as an array knowing its own length, array bounds checking, and other
> features geared towards protecting the programmer from stupid mistakes._

C++ has bounds-checked arrays that know their length if you want (hello,
_std::vector <T>_, or roll your own if you don't like that one). It just
doesn't endow the C arrays with it (for good reasons). The C compatibility of
C++ means that C++ interoperates easily with C API's without the overhead of
FFI.

~~~
gurkendoktor
I assume the author refers to "T *t = new T[x]", which probably predates and
inspired Java.

There is no reason why C++ can't provide a lengthof(x) function that returns
the length of arrays allocated using new[], since the length needs to be
stored internally anyway -- otherwise delete[] wouldn't know how many
destructors to call. It would also be great if there was a realloc()
equivalent that did the right thing with regards to constructors/destructors,
because it's not possible to build this functionality on top of C's realloc().

new[] and delete[] are frustrating. If you "typedef int X[5]", how do you
correctly free one instance of X - "delete new X" or "delete[] new X"?

The problem is that vector<T> isn't great either. Only C++03 made it legal to
assume that vector<T> has contiguous storage (which is critical when
interfacing with C APIs), and only C++11 made it possible to transfer vectors
without expensive copies. But using rvalue references and copy elision
correctly is certainly not trivial, and using vector<T> as a building block
for your own data structures is in some ways more frustrating than using
new[].

I think C++ should deprecate new[] and delete[], add a library function
std::realloc_array<T>(ptr_or_null, length) that can be used to replace
new[]/delete[]/realloc() and another library function std::array_length(ptr),
and then vector<T> and other data structures could be built on top of that
with little overhead. But I don't see it happening.

------
jononor
I'm more annoyed that const is opt-in instead of the default. Though I guess
for C++ as a "better C" there wasn't much of an option to do that...

------
gurkendoktor
const is one of the reasons why I prefer strongly-typed languages based on
reference types. I want to love the no-overhead policy of C++, but value types
make const annoying (e.g. no vector<const string>) and require complicated
rvalue-reference mechanics to be efficient when working with nested data
structures.

In Java, where everything is an (expensive) reference type, building an
immutable LabeledPoint2D class is a no-brainer. "final String label; final
double x, y;" \- done. I find this much easier to reason about than the C++
equivalent where the const-ness only emerges from how you use the class.

Add Objective-C's system where Array<T>, Set<T>, String etc. are all
immutable, and only their derived types (MutableArray<T>, MutableSet<T>,
MutableString) are mutable, and you get a reasonably effective and efficient
implementation of tail-constness without extending your type system.

It's bizarre how C++ and D both try so hard to implement const, yet higher-
level languages that could easily have better const support don't really
bother (think Java, where you never know which List<T> is mutable).

