PART 10 Q41: What is `const correctness'? A: A program is `const correct' if it never mutates a constant object. This is achieved by using the keyword `const'. Ex: if you pass a String to a function `f()', and you wish to prohibit `f()' from modifying the original String, you can either pass by value: void f( String s ) { /*...*/ } or by constant reference: void f(const String& s ) { /*...*/ } or by constant pointer: void f(const String* sptr) { /*...*/ } but *not* by non-const ref: void f( String& s ) { /*...*/ } *nor* by non-const pointer: void f( String* sptr) { /*...*/ } Attempted changes to `s' within a fn that takes a `const String&' are flagged as compile-time errors; neither run-time space nor speed is degraded. Q42: Is `const correctness' a good goal? A: Declaring the `constness' of a parameter is just another form of type safety. It is almost as if a constant String, for example, `lost' its various mutative operations. If you find type safety helps you get systems correct (especially large systems), you'll find const correctness helps also. Short answer: yes, const correctness is a good goal. Q43: Is `const correctness' tedious? A: Type safety requires you to annotate your code with type information. In theory, expressing this type information isn't necessary -- witness untyped languages as an example of this. However in practice, programmers often know in their heads a lot of interesting information about their code, so type safety (and, by extension, const correctness) merely provide structured ways to get this information into their keyboards. Short answer: yes, const correctness is tedious. Q44: Should I try to get things const correct `sooner' or `later'? A: Back-patching const correctness is *very* expensive. Every `const' you add `over here' requires you to add four more `over there'. The snowball effect is magnificent -- unless you have to pay for it. Long about the middle of the process, someone stumbles on a function that needs to be const but can't be const, and then they know why their system wasn't functioning correctly all along. This is the benefit of const correctness, but it should be installed from the beginning. Short answer: CONST CORRECTNESS SHOULD NOT BE DONE RETROACTIVELY!! Q45: What is a `const member function'? A: A const member function is a promise to the caller not to change the object. Put the word `const' after the member function's signature; ex: class X { //... void f() const; }; Some programmers feel this should be a signal to the compiler that the raw bits of the object's `struct' aren't going to change, others feel it means the *abstract* (client-visible) state of the object isn't going to change. C++ compilers aren't allowed to assume the bitwise const, since a non-const alias could exist which could modify the state of the object (gluing a `const' ptr to an object doesn't promise the object won't change; it only promises that the object won't change **via that pointer**). I talked to Jonathan Shopiro at the C++AtWork conference, and he confirmed that the above view has been ratified by the ANSI-C++ standards board. This doesn't make it a `perfect' view, but it will make it `the standard' view. See the next few questions for more. Q46: What is an `inspector'? What is a `mutator'? A: An inspector inspects and a mutator mutates. These different categories of member fns are distinguished by whether the member fn is `const' or not. Q47: What is `casting away const in an inspector' and why is it legal? A: In current C++, const member fns are allowed to `cast away the const-ness of the "this" ptr'. Programmers use (some say `misuse') this to tickle internally used counters, cache values, or some other non-client-visible change. Since C++ allows you to use const member fns to indicate the abstract/meaning-wise state of the object doesn't change (as opposed to the concrete/bit-wise state), the `meaning' of the object shouldn't change during a const member fn. Those who believe `const' member fns shouldn't be allowed to change the bits of the struct itself call the `abstract const' view `Humpty Dumpty const' (Humpty Dumpty said that words mean what he wants them to mean). The response is that a class' public interface *should* mean exactly what the class designer wants it to mean, in Humpty Dumpty's words, `nothing more and nothing less'. If the class designer says that accessing the length of a List doesn't change the List, then one can access the length of a `const' List (even though the `len()' member fn may internally cache the length for future accesses). Some proposals are before the ANSI/ISO C++ standards bodies to provide syntax that allows individual data members to be designated as `can be modified in a const member fn' using a prefix such as `~const'. This would blend the best of the `give the compiler a chance to cache data across a const member fn', but only if aliasing can be solved (see next question). Q48: But doesn't `cast away const' mean lost optimization opportunities? A: If the object is constructed in the scope of the const member fn invocation, and if all the non-const member function invocations between the object's construction and the const member fn invocation are statically bound, and if every one of these invocations is also `inline'd, and if the ctor itself is `inline', and if any member fns the ctor calls are inline, then the answer is `Yes, the soon-to-be-standard interpretation of the language would prohibit a very smart compiler from detecting the above scenario, and the register cache would be unnecessarily flushed'. The reader should judge whether the above scenario is common enough to warrant a language change which would break existing code.