From: Greg Herlihy on
Seungbeom Kim wrote:
> Francis Glassborow wrote:
> I agree that when people use the term 'const reference' it can mean only
> one thing, but I think such usage should be discouraged, to keep the
> analogy among references, pointers, and iterators. (So, "be strict in
> what you say, and lenient in what you accept." :)) Why add the confusion
> to just save one word; things are most clearly described when there's no
> exception and everything can be described in a uniform way.

Such uniformity is misleading - because it creates the false impression
that name of a reference is analogous to the name of pointer. When the
reality is the names are used in opposite ways:

For example:

int * const p;

"p" names the const pointer object and not the object that it may be
pointing to (and which is not named in this declaration). With
reference declarations, the situation is just the opposite:

int& ref = i;

"ref" names the object being referenced ("a reference may be thought of
as the name of an object") and the there is no, other referencing
object. So ref is not a "reference to an int" as much as ref is "the
int being refererced" in this expression.

> > If we stop thinking of references as some kind of hidden pointer we have
> > a better chance of not confusing terminology used for speaking/writing
> > about references with that used for pointers.
>
> Even without thinking of references as some kind of hidden pointers (in
> implementation details), we already have the analogy and similarities
> among references, pointers, and iterators on a higher level, and I don't
> see why that adds the confusion. What makes references distinct in this
> problem is just that they are not objects and they cannot be const.

The name of a reference names an object (and therefore the name can be
used in the program just like an object). So at the very least "a
reference to const" and a "const reference" are synonymous - because
the object being refererced is none other than the object being named.
A "const reference" however is the more accurate (and should be the
preferred) term since the name is not so much referring to an object,
as much as it is an object that is being referred to.

Greg


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Greg Herlihy on
Francis Glassborow wrote:
> As for the way we write pointers to const, there are good reasons for
> preferring:
>
> int const * ptr;
>
> to
>
> const int * ptr;
>
> even though they have identical meanings.

And there are even better arguments in opposition - namely the fact
that in English, adjectives almost always precede the noun they modify.
So a "const(ant) int" is simply more idiomatic a phrase than "int
const(ant)". And in fact the only exception that comes to mind - and
about the only time where one would expect to see "int const" in any
significant numbers - would be while reading a volume of C++ poetry.

Furthermore, the fact that Bjarne prefers "const int" over "int const"
is a good enough reason for me. :)

I first came across a
> carefully worded rationale for this choice from Dan Saks more than a
> decade ago. In simple terms it is far too easy to confuse the later with
>
> int * const cptr;
>
> because programmers get used to thinking (correctly) that const atype
> and atype const are synonyms. Does this matter, well if no one ever
> aliased compound types with typedef provided names it would probably be
> relatively innocuous but we do use typedefs for compound types, and some
> use them to hide away that a type is a pointer. Some of those also then
> confuse the consequences of:
>
> typedef int * intptr;
>
> int i;
> const intptr ptr(i);
> intptr const ptr(i);
>
> Thinking that the first declares ptr to be a pointer to a const int and
> the second declares ptr to be a const pointer to int. Of course both
> declare ptr to be a const pointer to int.

I don't think the placement of "const" in the above examples - no
matter how judiciously selected - is going to do much to clean up the
mess that this program has managed to make of its type names. After
all, neither "ptr" declaration looks like a pointer declaraton. The
fact that "ptr" appears in the typedef names is far from conclusive.
Neither the Standard Library's auto_ptr nor the TR1 library's
shared_ptr are pointer types for example. In short there is no way of
interpreting these declarations accurately without knowing intptr's
actual type (which makes the intptr typedef itself rather pointless).

So rather than be forced to master C++'s incredibly confusing syntax of
const-qualified typedef declarations (and force other programmers
working on the same code in the future to do the same), a C++
programmer is likely to find that simply not mixing typedefs and const
qualifiers is the far more const-effective and practical programming
practice to adopt. In other words, a C++ programmer simply has to
declare the appropriate, const-qualified variation of a typedef - if
ever the program needs it. For example, a program that declares an int
pointer typedef may also need to declare up to three additonal
typedefs:

typedef int * IntPtr; // original typedef

// const variations that may be needed

typedef const int * ConstIntPtr;
typedef int * const IntConstPtr;
typedef const int * const ConstIntConstPtr;

Note how the components of each typedef name match (and follow the same
order as) the keywords in the type declaration.

Greg


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Greg Herlihy wrote:
> Francis Glassborow wrote:
> > As for the way we write pointers to const, there are good reasons for
> > preferring:

> > int const * ptr;

> > to

> > const int * ptr;

> > even though they have identical meanings.

> And there are even better arguments in opposition - namely the fact
> that in English, adjectives almost always precede the noun they modify.

Except that C++ isn't English. Otherwise, a pointer to int
would be declared "*int p;". And const(ant) pointer to int
"const *int p;". The whole point of the argument is that in
most cases, you don't have a choice; the modifier must come
after what it modifies. So there is a strong argument to be
coherent.

> So a "const(ant) int" is simply more idiomatic a phrase than "int
> const(ant)".

In English. What's idiomatic in C++ is what is actually used in
C++. In this particular case, I'd say that both are idiomatic:
historically, "const int* p;" was by far the most prevelant, but
today, I'd say that both are wide spread.

The real argument for post-positionning the const, of course, is
related to typedefs:

typedef int* PtrInt ;
const PtrInt pi1 ; // == int *const !!!

This sort of thing seems to create so much confusion in the
minds of beginners that it's better avoided.

Other than that, I'd say it's pretty much a stylistic issue, and
though I definitly prefer "int const* p", I'll use whatever the
coding guidelines say. I will point out the typedef problem to
whoever is responsible for maintaining the coding guidelines,
but it's not always trivial to change guidelines which have been
established for a certain time.

> And in fact the only exception that comes to mind - and
> about the only time where one would expect to see "int const" in any
> significant numbers - would be while reading a volume of C++ poetry.

Or reading C++ writing by some of the leading experts:
Vandevoorde, Josuttis...

> Furthermore, the fact that Bjarne prefers "const int" over "int const"
> is a good enough reason for me. :)

Does he? I never asked him what his current opinion is.

[...]
> So rather than be forced to master C++'s incredibly confusing syntax of
> const-qualified typedef declarations (and force other programmers
> working on the same code in the future to do the same), a C++
> programmer is likely to find that simply not mixing typedefs and const
> qualifiers is the far more const-effective and practical programming
> practice to adopt.

Surprisingly, I tend to agree, and think that typedef's should
be used sparingly, when they have real semantics, but not just
to try to mask the complexities of the C++ declaration syntax
(or worse, to reduce typing). I would almost never use a
typedef for a pointer to member function, for example. But I
have the impress that I'm a minority, and a lot of people prefer
the typedef'ed versions. Which means that any style adopted
should work well with typedef's as well.

--
James Kanze (GABI Software) email:james.kanze(a)gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gerhard Menzl on
Greg Herlihy wrote:

> Such uniformity is misleading - because it creates the false
> impression that name of a reference is analogous to the name of
> pointer. When the reality is the names are used in opposite ways:
>
> For example:
>
> int * const p;
>
> "p" names the const pointer object and not the object that it may be
> pointing to (and which is not named in this declaration). With
> reference declarations, the situation is just the opposite:
>
> int& ref = i;
>
> "ref" names the object being referenced ("a reference may be thought
> of as the name of an object") and the there is no, other referencing
> object. So ref is not a "reference to an int" as much as ref is "the
> int being refererced" in this expression.

Following your logic, and given:

struct B {};
struct D : B {};

void f()
{
D d;
B& r = d;
}

r were to be called "a reference to D", or, better still, a "D
reference". Consequently, given only

void g(B& b);

the parameter of g() would be of type "B or something derived from B, I
cannot tell for sure, reference".



--
Gerhard Menzl

Non-spammers may respond to my email address, which is composed of my
full name, separated by a dot, followed by at, followed by "fwz",
followed by a dot, followed by "aero".



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
In article <1162704219.682237.280390(a)h54g2000cwb.googlegroups.com>, Greg
Herlihy <greghe(a)pacbell.net> writes
>Francis Glassborow wrote:
>> As for the way we write pointers to const, there are good reasons for
>> preferring:
>>
>> int const * ptr;
>>
>> to
>>
>> const int * ptr;
>>
>> even though they have identical meanings.
>
>And there are even better arguments in opposition - namely the fact
>that in English, adjectives almost always precede the noun they modify.

:-) But I was not speaking of English but of C++ where we have to parse
declarations by identifying the name being declared and working outwards
from there. No other way of parsing C++ declarations makes consistent
sense.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]