5 ms·
Why Const Sucks
- gurkendoktor 9y agoconst 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).
- abacate 9y ago> 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.
- deleted 9y ago[deleted]
- signa11 9y ago> 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 9y agoI 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 9y ago> 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 :)
- jononor 9y agoI'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...
- kazinator 9y ago> 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 9y agoI 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.
- beojan 9y agoWell... .at() is bounds checked, but operator[] (which is what most people use) isn't. It should probably have been the other way around, I'd say.
- satish-setty 9y ago