By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,804 Members | 1,659 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,804 IT Pros & Developers. It's quick & easy.

Const inheriting

P: n/a
Hi all,

What is everyone's opinion of const inheriting? Should the object that
a pointer is pointing at inherit the constness of the pointer? Such as
in the case of a class having a pointer and then dereferencing that
pointer. Should the dereferenced pointer have the same constness of the
pointer as the pointer has the same constness as the class object?

Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.

Thanks for your participation,
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #1
Share this Question
Share on Google+
17 Replies


P: n/a
Adrian Hawryluk wrote:
What is everyone's opinion of const inheriting? Should the object
that a pointer is pointing at inherit the constness of the pointer? Such
as in the case of a class having a pointer and then
dereferencing that pointer. Should the dereferenced pointer have the
same constness of the pointer as the pointer has the same constness
as the class object?
Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.
I do not think this is viable as a restriction. As an option it would
likely be useful, but then you have this already, if you explicitly
make the object const in the declaration of the pointer itself:

type const * const pointer_to_object;

(instead of

object * const pointer_to_object; )

which should give you a const object

decltype(*pointer_to_object) & ref_to_object = *pointer_to_object;

(decltype would give 'type const', see a proposal on 'decltype').

If I misunderstood, I am sorry. Perhaps you could supply an example
of what you'd like your proposal to accomplish.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 17 '07 #2

P: n/a
Adrian Hawryluk wrote:
Hi all,

What is everyone's opinion of const inheriting? Should the object that
a pointer is pointing at inherit the constness of the pointer? Such as
in the case of a class having a pointer and then dereferencing that
pointer. Should the dereferenced pointer have the same constness of the
pointer as the pointer has the same constness as the class object?
No.

Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.
What kind of research?
Best

Kai-Uwe Bux
Mar 17 '07 #3

P: n/a
Victor Bazarov wrote:
Adrian Hawryluk wrote:
>What is everyone's opinion of const inheriting? Should the object
that a pointer is pointing at inherit the constness of the pointer? Such
as in the case of a class having a pointer and then
dereferencing that pointer. Should the dereferenced pointer have the
same constness of the pointer as the pointer has the same constness
as the class object?
Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.

I do not think this is viable as a restriction. As an option it would
likely be useful, but then you have this already, if you explicitly
make the object const in the declaration of the pointer itself:

type const * const pointer_to_object;

(instead of

object * const pointer_to_object; )

which should give you a const object

decltype(*pointer_to_object) & ref_to_object = *pointer_to_object;

(decltype would give 'type const', see a proposal on 'decltype').

If I misunderstood, I am sorry. Perhaps you could supply an example
of what you'd like your proposal to accomplish.
Ok, pointers on the stack do have some reasons for not
inheriting(?)/promoting(?) constness to the type it is pointing at, for
the reason that you may want the compiler to know (and disallow the
programmer later on) from modifying the pointer, while still allowing
modifications of the object pointed at. I agree with that.

What I am suggesting is when they are used in classes/struts. Here is
an example:

class Class
{
int * pNumber;
public:
Class() : pNumber(new int(5)) {}

// assume either proper copy constructor or inaccessible one

T* number() const { return pNumber; } // not flagged as error
};

Yes, this is a contrived trivial example and is easily 'fixed', but it
is to show a point. A programmer /may inadvertently/ do this by
mistake. And then some other programmer exploits it, by changing the
value pointed at by pNumber to, say 6.

Should this be allowed by the compiler? I've heard that some say it
shouldn't because it breaks const correctness, allowing someone who has
a const 'handle' to an object to be able to indirectly change the state
of the object, such that calling a const member may result in not the
same value if accessed more than once from the same const handle. Note
that I am ignoring the fact that the originator of the const handle may
have a non-const handle and may change that object's internals at any
time. This is probably why M$ C# does not have a const keyword but uses
the readonly keyword instead.

I've also heard that this was not done because it would break the C++
supersetness(if there is such a word :)) of C (though at the moment,
that is currently broken with C99 standard).

Comments?
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #4

P: n/a
Kai-Uwe Bux wrote:
Adrian Hawryluk wrote:
>Hi all,

What is everyone's opinion of const inheriting? Should the object that
a pointer is pointing at inherit the constness of the pointer? Such as
in the case of a class having a pointer and then dereferencing that
pointer. Should the dereferenced pointer have the same constness of the
pointer as the pointer has the same constness as the class object?

No.
Very succinct :). Now why? Please see my second post for more info as
to what I am getting at before you answer. Thanks.
>Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.

What kind of research?
Language research. I am also making a memory management template
library which may use these ideas. I need to find a middle ground so
that the library is usable to as large an audience as possible.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #5

P: n/a
Adrian Hawryluk wrote:
Kai-Uwe Bux wrote:
>Adrian Hawryluk wrote:
>>Hi all,

What is everyone's opinion of const inheriting? Should the object that
a pointer is pointing at inherit the constness of the pointer? Such as
in the case of a class having a pointer and then dereferencing that
pointer. Should the dereferenced pointer have the same constness of the
pointer as the pointer has the same constness as the class object?

No.

Very succinct :). Now why? Please see my second post for more info as
to what I am getting at before you answer. Thanks.
Looking at the example from your other post, I think you can achieve what
you want without changes to the core language:

template < typename T >
class const_inherit_ptr {

T * the_ptr;

public:

friend
void deallocate ( const_inherit_ptr ptr ) {
delete ( ptr.the_ptr );
}

const_inherit_ptr ( T * ptr = 0 )
: the_ptr ( ptr )
{}

T * operator-( void ) {
return ( the_ptr );
}

T const * const operator-( void ) const {
return ( the_ptr );
}

T & operator* ( void ) {
return ( *the_ptr );
}

T const & operator* ( void ) const {
return ( *the_ptr );
}

operator T * ( void ) {
return ( the_ptr );
}

operator T const * ( void ) const {
return ( the_ptr );
}

};
class Class {

const_inherit_ptr<intpNumber;

public:

Class()
: pNumber(new int(5))
{}

~Class() {
deallocate( pNumber );
}

// the commented line causes an error
// int * number() const {
int const * number() const {
return pNumber;
}

};

int main ( void ) {

Class x;

x.number();
}

If you want this kind of protection, you can request it.

There is no need to restrict the expressive power of the core language. The
pointer and the pointee are two different objects. It should be possible to
make them const/non-const independently. In other word, if someone does

class X {

some_type * the_ptr;

public:

some_type * some_method ( void ) const;

};

it is far from clear that this is an error.

>>Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.

What kind of research?

Language research. I am also making a memory management template
library which may use these ideas. I need to find a middle ground so
that the library is usable to as large an audience as possible.
Sounds interesting.
Best

Kai-Uwe Bux
Mar 17 '07 #6

P: n/a
Kai-Uwe Bux wrote:
Adrian Hawryluk wrote:
>Kai-Uwe Bux wrote:
>>Adrian Hawryluk wrote:

Hi all,

What is everyone's opinion of const inheriting? Should the object that
a pointer is pointing at inherit the constness of the pointer? Such as
in the case of a class having a pointer and then dereferencing that
pointer. Should the dereferenced pointer have the same constness of the
pointer as the pointer has the same constness as the class object?
No.
Very succinct :). Now why? Please see my second post for more info as
to what I am getting at before you answer. Thanks.

Looking at the example from your other post, I think you can achieve what
you want without changes to the core language:

template < typename T >
class const_inherit_ptr {

T * the_ptr;

public:

friend
void deallocate ( const_inherit_ptr ptr ) {
delete ( ptr.the_ptr );
}

const_inherit_ptr ( T * ptr = 0 )
: the_ptr ( ptr )
{}

T * operator-( void ) {
return ( the_ptr );
}

T const * const operator-( void ) const {
return ( the_ptr );
}

T & operator* ( void ) {
return ( *the_ptr );
}

T const & operator* ( void ) const {
return ( *the_ptr );
}

operator T * ( void ) {
return ( the_ptr );
}

operator T const * ( void ) const {
return ( the_ptr );
}

};
Yeah, I've posted something similar in another thread just the other
day. Though, the deallocate() function is a nice touch. :) The
opearator T*() function (and its respective const version) may not work
in all cases due to template deduction rules. You also forgot to
overload the operator&() function, and now that I look at my own code,
operator T*() should probably be operator T*&() for arithmetic operators
with side effects to work without overloading them as well.
[snip]

If you want this kind of protection, you can request it.
More or less.
There is no need to restrict the expressive power of the core language. The
pointer and the pointee are two different objects. It should be possible to
make them const/non-const independently. In other word, if someone does
You misunderstand, I'm not trying to restrict the core language, I have
no reason to. I'm just trying to elicit opinions from people who use
the language to a very in-depth degree. To find out what their feelings
are about this issue that I am bringing up. (I would be extremely
surprised that there are only two people out there who have an opinion,
this is a newsgroup after all. ;))
class X {

some_type * the_ptr;

public:

some_type * some_method ( void ) const;

};

it is far from clear that this is an error.
I agree that it is far from clear given the interface, but I'm not
talking about the interface here, I'm talking about the underlying
implementation. Given that implementation, in what case is it far from
clear that the programmer has made an error? This can make it more
difficult for maintainer of the code base, who may or may not be the
original coder. There are many mistakes that some programmer has done
at some point or other that have been averted by the compiler
complaining about it. It is for this reason that I am trying to asking
*everyone* about this question.

If some_method() const returns a pointer to a non-const object, it is
currently forbidden in C++ that it return a pointer to a non-const type
that is pointing at the internal _aggregate_ object of that class. Does
it not make sense then to extrapolate this idea to other objects that
the class object is pointing at?

There is the mutable keyword which would allow for modifying internal
information in a more deliberate manner. As well as const_cast which
would be again more deliberate mechanism showing that the programmer
truly intended to do this.
>>>Yes, I am aware that C++ does not do this. I just want to know
everyones opinion about this subject for research.
What kind of research?
Language research. I am also making a memory management template
library which may use these ideas. I need to find a middle ground so
that the library is usable to as large an audience as possible.

Sounds interesting.
Thanks, I'm hoping that it turns the computing industry on its head ;)
by making handling pointers far safer than the current 'smart pointers'
ever could and being just as fast if not faster.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #7

P: n/a
Dnia Sat, 17 Mar 2007 20:48:28 +0000, Adrian Hawryluk napisał(a):
If some_method() const returns a pointer to a non-const object, it is
currently forbidden in C++ that it return a pointer to a non-const type
that is pointing at the internal _aggregate_ object of that class. Does
it not make sense then to extrapolate this idea to other objects that
the class object is pointing at?
Not in every case.
The fact that some object is constant doesn't implicate that the objects
pointed by its internal pointers are constant also. It depends on that
that pointed objects are sub-parts of the whole, or if they're independent
objects only pointed to by the main object. In the first case, the
constness of the main object could have impact on constness of its
sub-objects pointed by internal pointers. It might be pointers to some
resources used internally by the main object. On the second case, the
constness of the main object shouldn't demand constness on independent
objects, because they might be also linked from other main object,
which is non-const. These are my 3 bits on that subject ;)

--
SasQ
Mar 17 '07 #8

P: n/a
SasQ wrote:
Dnia Sat, 17 Mar 2007 20:48:28 +0000, Adrian Hawryluk napisał(a):
>If some_method() const returns a pointer to a non-const object, it is
currently forbidden in C++ that it return a pointer to a non-const type
that is pointing at the internal _aggregate_ object of that class. Does
it not make sense then to extrapolate this idea to other objects that
the class object is pointing at?

Not in every case.
The fact that some object is constant doesn't implicate that the objects
pointed by its internal pointers are constant also. It depends on that
that pointed objects are sub-parts of the whole, or if they're independent
objects only pointed to by the main object. In the first case, the
constness of the main object could have impact on constness of its
sub-objects pointed by internal pointers. It might be pointers to some
resources used internally by the main object. On the second case, the
constness of the main object shouldn't demand constness on independent
objects, because they might be also linked from other main object,
which is non-const.
Interesting. But still, wouldn't that be better handled by mutable (or
less so by const_cast) making this more explicit, thus showing this is
indeed the intent? IIRC, mutable's original intent was to show that an
object with this keyword did not change the logical constness of the
encompassing object, and would be better suited for this.
These are my 3 bits on that subject ;)
You like using octal? :) I'm a hex man myself. ;)
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 18 '07 #9

P: n/a
Adrian Hawryluk wrote:
SasQ wrote:
>Dnia Sat, 17 Mar 2007 20:48:28 +0000, Adrian Hawryluk napisa?(a):
>>If some_method() const returns a pointer to a non-const object, it is
currently forbidden in C++ that it return a pointer to a non-const type
that is pointing at the internal _aggregate_ object of that class. Does
it not make sense then to extrapolate this idea to other objects that
the class object is pointing at?

Not in every case.
The fact that some object is constant doesn't implicate that the objects
pointed by its internal pointers are constant also. It depends on that
that pointed objects are sub-parts of the whole, or if they're
independent objects only pointed to by the main object. In the first
case, the constness of the main object could have impact on constness of
its sub-objects pointed by internal pointers. It might be pointers to
some resources used internally by the main object. On the second case,
the constness of the main object shouldn't demand constness on
independent objects, because they might be also linked from other main
object, which is non-const.

Interesting. But still, wouldn't that be better handled by mutable (or
less so by const_cast) making this more explicit, thus showing this is
indeed the intent? IIRC, mutable's original intent was to show that an
object with this keyword did not change the logical constness of the
encompassing object, and would be better suited for this.
We need to distinguish:

a) changing the core language rules of C++ with regard to pointers.
b) considerations for designing a new language.

(a) is a bad idea, and you already said upthread that you are not suggesting
this.

(b) I do not really care whether I have to type

T *
T const *
T * const
T const * const

or

T *
T const *
T mutable * const
T * const

I have to admits, that I find the current C++ a little more appealing.

And now for the more tricky. What are the proposed equivalents of:

T * *
T const * *
T * const *
T * * const
T const * const *
T const * * const
T * const * const
T const * const * const
Best

Kai-Uwe Bux
Mar 18 '07 #10

P: n/a
Kai-Uwe Bux wrote:
We need to distinguish:

a) changing the core language rules of C++ with regard to pointers.
b) considerations for designing a new language.
I go with c:

c) considerations for designing a new library
>
(a) is a bad idea, and you already said upthread that you are not suggesting
this.
Right.
(b) I do not really care whether I have to type

T *
T const *
T * const
T const * const

or

T *
T const *
T mutable * const
T * const
So you don't care. But if the object that contained this type was
promoted to a const, would it be acceptable to you that all non-const in
that chain become const, resulting in: T const * const? And if the
mutable keyword was used would it be acceptable if all non-const in the
chain would stay mutable in the case of the enclosing object becoming const?
I have to admits, that I find the current C++ a little more appealing.
Why do you? Is it because it is what you are used to, or because it is
helpful in keeping bugs out of your code, or is it because it helps in
the writing of good code, or... what?
And now for the more tricky. What are the proposed equivalents of:

T * *
T const * *
T * const *
T * * const
T const * const *
T const * * const
T * const * const
T const * const * const
I am not advocating the removal of those. I /am/ asking if promoting an
object's type to const, causing an encapsulated pointer chain to promote
to const I described above is a) good, b) bad, c) doesn't matter. And I
would appreciate knowing the reasons that make you think this.

This would for example leave open the what you just stated in your
previous example, _but_ would cause the chain to promote to const if the
enclosing object was promoted to const like this:

T const * const * const

Is what I am asking reasonable? If not, then why not?

Thank you for your feedback, it is greatly appreciated.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 18 '07 #11

P: n/a
Adrian Hawryluk wrote:
Kai-Uwe Bux wrote:
>We need to distinguish:

a) changing the core language rules of C++ with regard to pointers.
b) considerations for designing a new language.

I go with c:

c) considerations for designing a new library
I don't understand this one. How can a library make the constness of a raw
pointer affect the constness/non-constness of the pointee?

>(a) is a bad idea, and you already said upthread that you are not
suggesting this.

Right.
>(b) I do not really care whether I have to type

T *
T const *
T * const
T const * const

or

T *
T const *
T mutable * const
T * const

So you don't care. But if the object that contained this type was
promoted to a const, would it be acceptable to you that all non-const in
that chain become const, resulting in: T const * const?
I would consider that surprising. More importantly, I would like to know
which means you intend to provide to undo that effect. Only then will I be
able to compare the two scenarios.
And if the
mutable keyword was used would it be acceptable if all non-const in the
chain would stay mutable in the case of the enclosing object becoming
const?
Where would you put the mutable keyword?

>I have to admits, that I find the current C++ a little more appealing.

Why do you? Is it because it is what you are used to, or because it is
helpful in keeping bugs out of your code, or is it because it helps in
the writing of good code, or... what?
It appears to be more systematic. It uses only one keyword, not two that
mutually undo-one another. Also, the scope of the keyword is more local.

>And now for the more tricky. What are the proposed equivalents of:

T * *
T const * *
T * const *
T * * const
T const * const *
T const * * const
T * const * const
T const * const * const

I am not advocating the removal of those.
Are you proposing a change in their meaning?
I /am/ asking if promoting an
object's type to const, causing an encapsulated pointer chain to promote
to const I described above is a) good, b) bad, c) doesn't matter. And I
would appreciate knowing the reasons that make you think this.
So, we are thinking about a function like this:

struct X { Y* ptr };
void f ( X const & x );

Under your proposal, this function shall not be able to modify *x.ptr.

Which signature do you propose for a function that reserves the right to
modify pointees of pointers in const objects? I think it would be important
to have that in the signature and not hidden somewhere in the body.

Or would I have to prepare the struct X for this kind of use:

struct X { Y mutable * ptr };
Before judging your proposal, one would actually like to see it. So far,
there are many things that one has to guess.

This would for example leave open the what you just stated in your
previous example, _but_ would cause the chain to promote to const if the
enclosing object was promoted to const like this:

T const * const * const

Is what I am asking reasonable? If not, then why not?
Quite honestly, I do not see where you are headed. You mentioned a library,
and I just cannot fathom how these const-chaining issues can possibly enter
a library design (because I don't see how a library can affect core
language rules like the ones under discussion). Before I have a better
picture of the proposal, I cannot tell whether it is reasonable.
Best

Kai-Uwe Bux
Mar 18 '07 #12

P: n/a
Kai-Uwe Bux wrote:
Adrian Hawryluk wrote:
>Kai-Uwe Bux wrote:
>>We need to distinguish:

a) changing the core language rules of C++ with regard to pointers.
b) considerations for designing a new language.
I go with c:

c) considerations for designing a new library

I don't understand this one. How can a library make the constness of a raw
pointer affect the constness/non-constness of the pointee?
It is not. It is a template library that mimics a pointer. I am trying
to determine if it would be adventitious to use a scheme of const
promotion as I am describing here. Or would there be many people who
would balk at this.
>>(a) is a bad idea, and you already said upthread that you are not
suggesting this.
Right.
>>(b) I do not really care whether I have to type

T *
T const *
T * const
T const * const

or

T *
T const *
T mutable * const
T * const
So you don't care. But if the object that contained this type was
promoted to a const, would it be acceptable to you that all non-const in
that chain become const, resulting in: T const * const?

I would consider that surprising. More importantly, I would like to know
which means you intend to provide to undo that effect. Only then will I be
able to compare the two scenarios.
I'm not changing the language, you still have all the tools to remove
the const promotion (const_cast) or the ignore the const (mutable).
>And if the
mutable keyword was used would it be acceptable if all non-const in the
chain would stay mutable in the case of the enclosing object becoming
const?

Where would you put the mutable keyword?
I've been thinking about this. It may have to be put at each level of
the chain that the programmer wishes to remain mutable.
>>I have to admits, that I find the current C++ a little more appealing.
Why do you? Is it because it is what you are used to, or because it is
helpful in keeping bugs out of your code, or is it because it helps in
the writing of good code, or... what?

It appears to be more systematic. It uses only one keyword, not two that
mutually undo-one another. Also, the scope of the keyword is more local.
I'm not sure I understand. Could you provide an example?
>>And now for the more tricky. What are the proposed equivalents of:

T * *
T const * *
T * const *
T * * const
T const * const *
T const * * const
T * const * const
T const * const * const
I am not advocating the removal of those.

Are you proposing a change in their meaning?
No, just a change in how they are const promoted.
>I /am/ asking if promoting an
object's type to const, causing an encapsulated pointer chain to promote
to const I described above is a) good, b) bad, c) doesn't matter. And I
would appreciate knowing the reasons that make you think this.

So, we are thinking about a function like this:

struct X { Y* ptr };
void f ( X const & x );

Under your proposal, this function shall not be able to modify *x.ptr.
Correct.
Which signature do you propose for a function that reserves the right to
modify pointees of pointers in const objects? I think it would be important
to have that in the signature and not hidden somewhere in the body.
This is a constness thing. If an object x is const, then the function
f() shouldn't be able to change it, undermining the constness which
could change the result of a const member function call. Again, I am
ignoring the fact that there could be a non-const reference out there
which /could/ change the result of a const function call. But
currently, I am only worried about the local ability to disrupt constness.
Or would I have to prepare the struct X for this kind of use:

struct X { Y mutable * ptr };
Correct, mutable can still be use to do changes that would not affect
the _logical_ constness of the object. That of course is open to abuse,
but the mutable could always be abused, it is up to the programmer to
use it correctly.
Before judging your proposal, one would actually like to see it. So far,
there are many things that one has to guess.
The syntax would probably be something like this:

Current syntax | Library syntax
------------------------------+-----------------------------------------
struct X { Y* ptr }; | struct X { ptr<Yptr; };
------------------------------+-----------------------------------------
struct X { Y mutable * ptr } | struct X { mutable_ptr<Yptr; };
------------------------------+-----------------------------------------
struct X { Y mutable * * ptr }| struct X { mutable_ptr<mutable_ptr<Y
| ptr; };
|
| or if only one of the levels in the
| chain should be mutable then:
|
| struct X { ptr<mutable_ptr<Y ptr; };
|
| or:
|
| struct X { mutable_ptr<ptr<Y ptr; };
------------------------------+-----------------------------------------
>This would for example leave open the what you just stated in your
previous example, _but_ would cause the chain to promote to const if the
enclosing object was promoted to const like this:

T const * const * const

Is what I am asking reasonable? If not, then why not?

Quite honestly, I do not see where you are headed. You mentioned a library,
and I just cannot fathom how these const-chaining issues can possibly enter
a library design (because I don't see how a library can affect core
language rules like the ones under discussion). Before I have a better
picture of the proposal, I cannot tell whether it is reasonable.
As I said, I'm not changing the core language rules, but I am
considering strengthening the rules when it comes to using this library
I am developing. Would it be accepted or would the people be irked by
it? Is it better to strengthen the rules in favour of better coding
even if there are those who would be irked by it? Is this better
coding? IMHO, I believe so, but what says you, the people who would use it?

Does this make sense to you now? Is my argument valid to do it this
way? If not, why?
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 18 '07 #13

P: n/a
Dnia Sun, 18 Mar 2007 00:01:32 +0000, Adrian Hawryluk napisał(a):
Interesting. But still, wouldn't that be better handled by
mutable (or less so by const_cast) making this more explicit
Explicit for who? :)
The user of the class's object doesn't have to know how the
object's internals are handled and if they're const too or not.
That's not his/her problem.
The class's designer knows that already ;)

Look for the following examples:

EXAMPLE 1
"""""""""
We have class 'DBInterface' and 'DataBase'. Every object of
the 'DBInterface' class have a pointer 'usedDatabase' pointing
to some database it uses. Every 'DBInterface' object can be
an interface to only one database at once, but a database could
be accessed by many clients at once. The UML class model would be:

+--------------+
| DBInterface |
+--------------+ 1..n 1 +----------+
| usedDatabase |<>-------------------| Database |
| ... | +----------+
+--------------+ | ... |
+----------+

This means aggregation. So the database may exist independently.
Now create some objects to play with:

+--------------+ +--------------+
| DBInterface1 | | DBInterface2 |
+--------------+ +-----------+ +--------------+
| usedDatabase-|----->| Database1 |<-----|-usedDatabase |
+--------------+ +-----------+ +--------------+

And now: what if the 'DBInterface1' object will be declared const?
[maybe for showing that it's a read-only interface to database].
If the 'Database1' shared object should inherit constness of
one of its interfaces?
Of course not! :P Because the fact that one interface is read-only
doesn't implicate that all interfaces should only read from that
shared database. Other interfaces could write to database no matter
of that DBInterface1 can only read.

Now let's take a look on the second example:

EXAMPLE 2
"""""""""
We have 'Stream' class for handling streaming I/O.
Objects of that class may create objects of 'DataBuffer' class
dynamically from the free store and manage that object throug
a pointer. Every object of 'Stream' class can have one buffer
internally, and create it/destroy/reallocate on demand.
In UML that would be:

+--------+
| Stream |
+--------+ 1 1 +------------+
| buffer-|<#>--------| DataBuffer |
| ... | +------------+
+--------+ | ... |
+------------+

The relationship is now considered as composition [a stronger
kind of aggregation]. Even though DataBuffer is managed by a
pointer, its life is determined by the containing object.
Now the sub-object is treated as a part of a whole and doesn't
live outside of it. So its constness may be derived by it.
But here the problem doesn't exist as long as the data buffer
is an internal part of a stream, and the 'Stream' class's user
doesn't have to know about it and worry about. All the troubles
with constness lies in hands of a class's designer and might be
controlled by him/her.
>These are my 3 bits on that subject ;)

You like using octal? :) I'm a hex man myself. ;)
:D

--
SasQ
Mar 18 '07 #14

P: n/a
SasQ wrote:
Dnia Sun, 18 Mar 2007 00:01:32 +0000, Adrian Hawryluk napisał(a):
>Interesting. But still, wouldn't that be better handled by
mutable (or less so by const_cast) making this more explicit

Explicit for who? :)
The maintainer. Maintenance is what (IIRC) 80% of the people hours are
spent on in an application. :) Sometimes even the original developer
has problems remembering things s/he did last week or last month or last
year. And sometimes the programmer *gasp* ;) makes a mistake and does
something that they had determined was illegal sometime during the project.
The user of the class's object doesn't have to know how the
object's internals are handled and if they're const too or not.
That's not his/her problem.
The class's designer knows that already ;)
Tell that to the documenter. Oh wait, either a) there isn't one, b)
there wasn't time to prepare a document or c) you're lucky, I found the
document propping up the table leg in the corner. ;D
Look for the following examples:

EXAMPLE 1
"""""""""
We have class 'DBInterface' and 'DataBase'. Every object of
the 'DBInterface' class have a pointer 'usedDatabase' pointing
to some database it uses. Every 'DBInterface' object can be
an interface to only one database at once, but a database could
be accessed by many clients at once. The UML class model would be:

+--------------+
| DBInterface |
+--------------+ 1..n 1 +----------+
| usedDatabase |<>-------------------| Database |
| ... | +----------+
+--------------+ | ... |
+----------+

This means aggregation. So the database may exist independently.
Now create some objects to play with:

+--------------+ +--------------+
| DBInterface1 | | DBInterface2 |
+--------------+ +-----------+ +--------------+
| usedDatabase-|----->| Database1 |<-----|-usedDatabase |
+--------------+ +-----------+ +--------------+

And now: what if the 'DBInterface1' object will be declared const?
[maybe for showing that it's a read-only interface to database].
If the 'Database1' shared object should inherit constness of
one of its interfaces?
Of course not! :P Because the fact that one interface is read-only
doesn't implicate that all interfaces should only read from that
shared database. Other interfaces could write to database no matter
of that DBInterface1 can only read.
Um, constness is a local phenomenon. Other objects may have a non-const
reference to the database. Truly, const is a misnomer, from what I've
seen of C#, they dropped that keyword in place of readonly, probably for
that reason. Just because one object holds a const reference, doesn't
mean that it cannot change, it just means that the holder of the const
reference cannot change the object it is referring to.
Now let's take a look on the second example:

EXAMPLE 2
"""""""""
We have 'Stream' class for handling streaming I/O.
Objects of that class may create objects of 'DataBuffer' class
dynamically from the free store and manage that object throug
a pointer. Every object of 'Stream' class can have one buffer
internally, and create it/destroy/reallocate on demand.
In UML that would be:

+--------+
| Stream |
+--------+ 1 1 +------------+
| buffer-|<#>--------| DataBuffer |
| ... | +------------+
+--------+ | ... |
+------------+

The relationship is now considered as composition [a stronger
kind of aggregation]. Even though DataBuffer is managed by a
pointer, its life is determined by the containing object.
Now the sub-object is treated as a part of a whole and doesn't
live outside of it. So its constness may be derived by it.
But here the problem doesn't exist as long as the data buffer
is an internal part of a stream, and the 'Stream' class's user
doesn't have to know about it and worry about. All the troubles
with constness lies in hands of a class's designer and might be
controlled by him/her.
You are exactly right, but what I am proposing is not really meant for a
user of the object. It is really meant to be used by the designer(s)
and maintainer(s) of the object; to tighten up the code and prevent
inadvertent errors.

Your examples are very useful and helpful. If you have others, I would
be very interested in hearing them.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 18 '07 #15

P: n/a
I guess, no one in this newsgroup has any more opinions about const
promotion w.r.t. pointers and whether it could be useful in the context
of the development/maintenance/safety of a class?

I would really like to know if there is any solid reason for not
implementing it. C++ cannot change its core because it would break C
programmes, but when using a container to wrap the pointer, should it
allow for const promotion and have a separate mutable pointer container
that would keep the entire chain unaffected?

Example:
| Containing object | | Containing object
Raw | referenced as const | Pointer | referenced as const
Pointer | makes ptr look like | Container | makes ptr look like
--------+---------------------+----------------+-------------------------
T** | T**const | ptr<ptr<T | ptr<ptr<Tconstconst
--------+---------------------+----------------+-------------------------
mutable | T** | mutable_ptr< | ptr<ptr<T
T** | | ptr<T |
--------+---------------------+----------------+-------------------------
alternative | ptr< | ptr<ptr<T const
| mutable_ptr< |
| T |
------------------------------+----------------+-------------------------
redundant | mutable_ptr< | ptr<ptr<T
alternative | mutable_ptr< |
| T |
------------------------------+----------------+-------------------------

Any criticisms? Any dislikes? Any reason not to do this?

Is it possible that there is another newsgroup, forum, website which
would be more interested in this sort of thing? If so, which one?

Thanks for your help.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 19 '07 #16

P: n/a
Adrian Hawryluk wrote:
I guess, no one in this newsgroup has any more opinions about const
promotion w.r.t. pointers and whether it could be useful in the
context of the development/maintenance/safety of a class?
Is this a question.
I would really like to know if there is any solid reason for not
implementing it. C++ cannot change its core because it would break C
programmes,
No. It can't change its core *now* because it would break tons and
tons of *C++* code. I don't think we care about C compatibility too
much at this point any more (being able to compile C code, that is).
but when using a container to wrap the pointer, should it
allow for const promotion and have a separate mutable pointer
container that would keep the entire chain unaffected?
Whenever you write your own class, do as you feel necessary. You have
a problem to solve, I presume. So, solve it. I don't think I have
the same problem, so I'll do without your solution for now.
Example:
| Containing object | | Containing object
Raw | referenced as const | Pointer | referenced as const
Pointer | makes ptr look like | Container | makes ptr look like
--------+---------------------+----------------+-------------------------
T** | T**const | ptr<ptr<T | ptr<ptr<Tconst>
const
--------+---------------------+----------------+-------------------------
mutable | T** | mutable_ptr< | ptr<ptr<T T** |
| ptr<T |
--------+---------------------+----------------+-------------------------
alternative | ptr< | ptr<ptr<T const |
mutable_ptr< | | T |
------------------------------+----------------+-------------------------
redundant | mutable_ptr< | ptr<ptr<T alternative | mutable_ptr<
| | T |
------------------------------+----------------+-------------------------

Any criticisms? Any dislikes?
You mean, besides the bad taste in my mouth from YAPWT ("yet another
pointer wrapping template")?
Any reason not to do this?
Unless you're going to force me into using it, I don't care what you
do on your own time. :-) Don't you know the saying "when a dog has
nothing to do, it ..."?
Is it possible that there is another newsgroup, forum, website which
would be more interested in this sort of thing? If so, which one?
You could try 'comp.lang.c++.moderated', the crowd there is thinner and
more advanced folks tend to hang out there rather than here.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 19 '07 #17

P: n/a
Victor Bazarov wrote:
Adrian Hawryluk wrote:
>I guess, no one in this newsgroup has any more opinions about const
promotion w.r.t. pointers and whether it could be useful in the
context of the development/maintenance/safety of a class?

Is this a question.
That is a statement? ;) I figure that I have quite clearly posed a
question, so I must not be understanding what you are trying to say.
>I would really like to know if there is any solid reason for not
implementing it. C++ cannot change its core because it would break C
programmes,

No. It can't change its core *now* because it would break tons and
tons of *C++* code. I don't think we care about C compatibility too
much at this point any more (being able to compile C code, that is).
True, the original reason was not to break C code, now it's just not to
break code. :)
>but when using a container to wrap the pointer, should it
allow for const promotion and have a separate mutable pointer
container that would keep the entire chain unaffected?

Whenever you write your own class, do as you feel necessary. You have
a problem to solve, I presume. So, solve it. I don't think I have
the same problem, so I'll do without your solution for now.
Sure.
>Example:
| Containing object | | Containing object
Raw | referenced as const | Pointer | referenced as const
Pointer | makes ptr look like | Container | makes ptr look like
--------+---------------------+----------------+-------------------------
T** | T**const | ptr<ptr<T | ptr<ptr<Tconst>
const
--------+---------------------+----------------+-------------------------
mutable | T** | mutable_ptr< | ptr<ptr<T T** |
| ptr<T |
--------+---------------------+----------------+-------------------------
alternative | ptr< | ptr<ptr<T const |
mutable_ptr< | | T |
------------------------------+----------------+-------------------------
redundant | mutable_ptr< | ptr<ptr<T alternative | mutable_ptr<
| | T |
------------------------------+----------------+-------------------------

Any criticisms? Any dislikes?

You mean, besides the bad taste in my mouth from YAPWT ("yet another
pointer wrapping template")?
:) the representation I described was some generic thing I through up to
make it understood. My real goal is not just wrapping the pointer, but
to do complete memory management with O(1) complexity, debugging tools
and no garbage collector. That is the research that I am doing.
> Any reason not to do this?

Unless you're going to force me into using it, I don't care what you
do on your own time. :-) Don't you know the saying "when a dog has
nothing to do, it ..."?
No, what does it do. Do tell. :)
>Is it possible that there is another newsgroup, forum, website which
would be more interested in this sort of thing? If so, which one?

You could try 'comp.lang.c++.moderated', the crowd there is thinner and
more advanced folks tend to hang out there rather than here.
Thanks for the info.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 19 '07 #18

This discussion thread is closed

Replies have been disabled for this discussion.