From: Lourens Veen on 6 Nov 2006 17:13 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 8 Nov 2006 04:30 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 9 Nov 2006 08:35 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 10 Nov 2006 13:31 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 10 Nov 2006 13:53
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! ] |