Excellent explanation - thanks, Alan!

> -----Original Message-----
> From: Alan Conway [mailto:acon...@redhat.com]
> Sent: Thursday, April 02, 2015 12:19 PM
> To: dev
> Subject: C++ tip: use of const [ignore at will]
> 
> I'm looking at some code that has a bunch of const mistakes in it, thought I'd
> offer a quick tip.
> 
> The placement of const in C++ is confusing. The secret is that there is 
> actually
> a simple, logical rule for const with one wildly confusing exception, and
> almost everybody uses the exception. The actual C++ rule
> is:
> 
> "const refers to the thing that comes _before_ it *except* if const is the 
> first
> thing in the declaration in which case it refers to the thing _after_ it"
> 
> If you always put const *after* the thing it modifies, complex type
> expressions are easy to read. Many (most?) programmers don't, I still don't
> in Qpid because I don't want pile inconsistency on confusion. But once you
> know the rule, you can mentally flip that first const around and it all 
> becomes
> clear.
> 
> [Aside: The Sacred Rule of C++ is: "Never break any code written since the
> dawn of C no matter how insanely complex the language becomes".
> const-before works for simple expressions and was used in early C++. By the
> time they realized it *doesn't* work for complex expressions, people had
> written code so the Sacred Rule kicked in and now we have const-after-
> except-when-its-before.]
> 
> const-before is clear enough for simple expressions:
> 
>     const int* p;  // Cannot use p to modify the int.
> 
> But what about this:
> 
>     const int* const p; // Huh? What?
> 
> Now look how easy it is to read if you stick to const-after:
> 
>     int const *p;        // int is const, cannot modify the int.
>     int const *const p;  // int is const and * is const: cannot modify the 
> int or
> make the pointer point elsewhere
>     int *const p;        // * is const: *can* modify the int but *cannot* 
> make the
> pointer point elsewhere
> 
> Here's the huh, what example again but now you can flip it:
> 
>     const int* const p; // Huh? What?
>     int const * const p; // Ahhh, yes, int is const, * is const. Of course.
> 
> 
> Some of the above examples are unrealistic though, let me explain.
> 
> It is often useful to declare a pointer to a const value, so whoever gets the
> pointer can't mess with the value:
> 
>    foo const *p // the logical way
>    const foo *p // the ugly way
> 
> But there is *rarely* any point in making the pointer or reference
> *itself* const. In particular it is *never* useful to make a function 
> parameter
> or return type const. These const are all utterly useless:
> 
>     foo *const f(const int i1, int const i2, foo *const p)
> 
> In C++ parameters are passed by value so a function can *never* change its
> parameters, const or not. It can only change things the parameters point (or
> refer) to.
> 
> However declaring that the things the parameters point/refer to *is* useful.
> 
>      foo const* f(foo const* p, foo const& r)
>      const foo* f(const foo* p, const foo& r) // The ugly version
> 
> It can be useful to declare pointers const if they themselves are being
> pointed at or referred to or are part of something being pointed at or
> referred to, but not if they are being passed as parameters.
> 
> References work like pointers insofar as declaring the thing they refer to as
> const. Unlike pointers you can't declare the reference itself to be const:
> 
>      int const &i = ...; // Good, can't use reference to change the int
>      int& const i = ...; // WRONG, reference itself can't be const.
> 
> This is because references are already immutable, you can't change what
> they refer to. C++ references are like pointers in a frilly dress and high 
> heels -
> prettier but less mobile.
> 
> Cheers,
> Alan.
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@qpid.apache.org For additional
> commands, e-mail: dev-h...@qpid.apache.org

Reply via email to