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