From: Lourens Veen on
James Kanze wrote:
>
> 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.

I'm not sure if I'm a beginner, but I don't see why this should be
surprising:

const A a; // can't change a
const B b; // can't change b
const PtrInt pi1; // can't change pi1

If you declare an object const, that means that you can't change it.
Unless it is a pointer or a reference, in which case you need to be
careful that the const is in the right place and means what you think
it means. But if I see PtrInt I don't think of a pointer, I think of
an object that behaves somewhat like a pointer, most likely a smart
pointer.

If PtrInt pointed to a const int, I'd expect it to be named
PtrConstInt (as identifiers /are/ in English).

Lourens


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

From: Yechezkel Mett on
James Kanze wrote:
> 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.

There I disagree. In "int*" int is the modifier; what we have here is a
kind of pointer, not a kind of int. Of course, the "int *const" argument
is still there - const must follow what it modifies in this case.
However, given the inherent inconsistencies, I prefer to put the const
closest to what it modifies and furthest from what it doesn't modify,
thus "const int*" and "int *const", making it obvious what is const in
each case.

Yechezkel Mett

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

From: Earl Purple on

James Kanze wrote:

>
> 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.

And to intermediate (and even fairly advanced) programmers they get
confused in the world of smart pointers.

const T* p; // pointer to const T
const shared_ptr< T > p; // not quite what they wanted...

A typical smart pointer implementer might try this:

template < typename T >
class SmartPointer
{
T* ptr;

public:
T& operator*() { return *ptr; }
const T& operator *() const { return *ptr; }

// plus other stuff
};

void func( const SmartPointer< T > & p ) // surely the can't modify the
T
{
SmartPointer<T> dup( p ); // assuming we have a copy-constructor
T & t = *dup; // hey dup is non-const

t.non_const_method(); // oh yes I can modify it.
}


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

From: Lourens Veen on
Yechezkel Mett wrote:

> James Kanze wrote:
>> 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.
>
> There I disagree. In "int*" int is the modifier; what we have here
> is a kind of pointer, not a kind of int. Of course, the "int *const"
> argument is still there - const must follow what it modifies in this
> case.

I agree, and I think this could be avoided as well. Assuming template
typedefs, what about the following:

template <typename T>
typedef T* ptr;

Now we can use

const ptr<T> p1; // const pointer to T
ptr<const T> p2; // pointer to const T
const shared_ptr<T> p3; // const shared pointer to T
shared_ptr<const T> p4; // shared pointer to const T

and so on. That's consistent with smart pointers and templates in
general, and reads left-to-right. The same mechanism could be used
for references (and rvalue references) to avoid all this confusion.

Also, like in the case with C++-style casts, it would make it easier
to find bare pointers in large amounts of code.

Lourens


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

From: James Kanze on
Lourens Veen wrote:
> James Kanze wrote:

> > 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.

> I'm not sure if I'm a beginner, but I don't see why this should be
> surprising:

> const A a; // can't change a
> const B b; // can't change b
> const PtrInt pi1; // can't change pi1

Because that's not the way it works in general:

const int* pi ; // can't change pi ??

Note that C++ declaration syntax is not easy, and putting the
const behind, rather than before, doesn't magically make it so.
I find it better, but the difference isn't necessarily enormous.
No matter where you put the const, unless the reader knows how
the declaration syntax really works, there will be cases where
it is less than obvious.

--
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! ]