For Programmers: Free Programming Magazines  


Home > Archive > VC STL > March 2006 > Smart pointer: const wrapped object pointer?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Smart pointer: const wrapped object pointer?
Alex Blekhman

2006-03-02, 3:59 am

Hello,

I noticed that std::auto_ptr (in VC2005) declares wrapped
object pointer like that:

....
private:
const _Ty *_Myptr; // the wrapped object pointer
....

Any reason to have `const' modifier there? I looked for
examples of auto_ptr implementation out there (including
Scott Meyers' "More Effective C++"). None of them stores raw
pointer with `const' modifier. So, my question is: Why
wrapped raw pointer declared to point to const object?

Thanks
Alex


David Wilkinson

2006-03-03, 7:04 pm

Alex Blekhman wrote:

> Hello,
>
> I noticed that std::auto_ptr (in VC2005) declares wrapped
> object pointer like that:
>
> ...
> private:
> const _Ty *_Myptr; // the wrapped object pointer
> ...
>
> Any reason to have `const' modifier there? I looked for
> examples of auto_ptr implementation out there (including
> Scott Meyers' "More Effective C++"). None of them stores raw
> pointer with `const' modifier. So, my question is: Why
> wrapped raw pointer declared to point to const object?
>
> Thanks
> Alex
>
>


Alex:

How come nobody has answered this? It seems very strange to me. I don't
have VC8 yet, so I can't see the rest of the class, but wouldn't this
prevent you from calling non-const methods on the auto-pointer?

David Wilkinson
Alex Blekhman

2006-03-03, 7:04 pm

David Wilkinson wrote:
>
> How come nobody has answered this? It seems very strange
> to me. I don't have VC8 yet, so I can't see the rest of
> the class, but wouldn't this prevent you from calling
> non-const methods on the auto-pointer?


Yes, that seems strange. I just guess that everybody is
speechless. :) Actually, rest of the calss didn't change
much from VC7.1. Except type of pointer, which is specified
now. I don't have VC7.1 at hand right now, but I can see in
that post of P.J. Plauger that VC7.1 contains following
implementation:

"dinkumware fixes for VC7.1?"
http://groups.google.com/group/micr...8780e38e56ec7bb

As you can see, there contained pointer is typeless at all:

const void *_Myptr; // the wrapped object pointer

I reckon that type was added later, but `const' modifier
survived fixes. As you pointed `const' would prevent to
access wrapped pointer from non-const memberst. To avoid it
wrapped pointer is C-casted every time it accessed as
non-const. For example:

_Ty *get() const _THROW0()
{ // return wrapped pointer
return ((_Ty *)_Myptr);
}

I found the whole issue when my own smart pointer (mostly
copy-pasted from std::auto_ptr) was denied compilation under
Linux. I don't know right now which compiler other team used
to build it, but C-cast didn't succeed to remove constness
of pointer. Assuming that C-cast is equivalent to
reinterpret_cast, then compiler rightly denies it. (See
other post in this NG:

"Yet another bug (.NET 2002)"
http://groups.google.com/group/micr...f9d27a298d31dbb

Thanks
Alex


Alex Blekhman

2006-03-03, 7:04 pm

David Wilkinson wrote:
>
> How come nobody has answered this? It seems very strange
> to me. I don't have VC8 yet, so I can't see the rest of
> the class, but wouldn't this prevent you from calling
> non-const methods on the auto-pointer?


Yes, that seems strange. I just guess that everybody is
speechless. :) Actually, rest of the calss didn't change
much from VC7.1. Except type of pointer, which is specified
now. I don't have VC7.1 at hand right now, but I can see in
that post of P.J. Plauger that VC7.1 contains following
implementation:

"dinkumware fixes for VC7.1?"
http://groups.google.com/group/micr...8780e38e56ec7bb

As you can see, there contained pointer is typeless at all:

const void *_Myptr; // the wrapped object pointer

I reckon that type was added later, but `const' modifier
survived fixes. As you pointed `const' would prevent to
access wrapped pointer from non-const memberst. To avoid it
wrapped pointer is C-casted every time it accessed as
non-const. For example:

_Ty *get() const _THROW0()
{ // return wrapped pointer
return ((_Ty *)_Myptr);
}

I found the whole issue when my own smart pointer (mostly
copy-pasted from std::auto_ptr) was denied compilation under
Linux. I don't know right now which compiler other team used
to build it, but C-cast didn't succeed to remove constness
of pointer. Assuming that C-cast is equivalent to
reinterpret_cast, then compiler rightly denies it. (See
other post in this NG:

"Yet another bug (.NET 2002)"
http://groups.google.com/group/micr...f9d27a298d31dbb

Thanks
Alex


David Wilkinson

2006-03-03, 7:04 pm

Alex Blekhman wrote:

> David Wilkinson wrote:
>
>
>
> Yes, that seems strange. I just guess that everybody is
> speechless. :) Actually, rest of the calss didn't change
> much from VC7.1. Except type of pointer, which is specified
> now. I don't have VC7.1 at hand right now, but I can see in
> that post of P.J. Plauger that VC7.1 contains following
> implementation:
>
> "dinkumware fixes for VC7.1?"
> http://groups.google.com/group/micr...8780e38e56ec7bb
>
> As you can see, there contained pointer is typeless at all:
>
> const void *_Myptr; // the wrapped object pointer
>
> I reckon that type was added later, but `const' modifier
> survived fixes. As you pointed `const' would prevent to
> access wrapped pointer from non-const memberst. To avoid it
> wrapped pointer is C-casted every time it accessed as
> non-const. For example:
>
> _Ty *get() const _THROW0()
> { // return wrapped pointer
> return ((_Ty *)_Myptr);
> }
>
> I found the whole issue when my own smart pointer (mostly
> copy-pasted from std::auto_ptr) was denied compilation under
> Linux. I don't know right now which compiler other team used
> to build it, but C-cast didn't succeed to remove constness
> of pointer. Assuming that C-cast is equivalent to
> reinterpret_cast, then compiler rightly denies it. (See
> other post in this NG:
>
> "Yet another bug (.NET 2002)"
> http://groups.google.com/group/micr...f9d27a298d31dbb
>
> Thanks
> Alex
>
>


Alex:

Yes, I figured there must be a cast, which should be a const_cast
really. But surely a C-style cast can cast away const? It's not the same
as reinterpret_cast. You say gcc would not allow it? Clearly VC8 allows it.

David Wilkinson
Alex Blekhman

2006-03-04, 3:59 am

David Wilkinson wrote:
>
> Yes, I figured there must be a cast, which should be a
> const_cast really. But surely a C-style cast can cast
> away const? It's not the same as reinterpret_cast.
> You say gcc would not allow it? Clearly VC8 allows it.


I'll check the compiler they use for Linux builds when I get
to office on Sunday. Regarding const_cast, I agree that it
should be used there. Actually, I think that pointer to
`const' should not be there at all. Then there is no need in
any cast. I can't think of any reason why `const' should be
artificially added and then removed by C-style cast each
time pointer is used.

I rechecked C-style cast in The Standard, and yes, you
right, C-style cast is not equivalent to reinterpret_cast.
Moreover, C-style cast should remove constness, as well:

5.4 Explicit type conversion (cast notation)
....
5 The conversions performed by
— a const_cast (5.2.11),
— a static_cast (5.2.9),
— a static_cast followed by a const_cast,
— a reinterpret_cast (5.2.10), or
— a reinterpret_cast followed by a const_cast,
can be performed using the cast notation of explicit type
conversion.
....


Alex


Alex Blekhman

2006-03-05, 7:00 pm

OK, I just removed `const' from the wrapped pointer
declaration.


David Wilkinson

2006-03-05, 7:00 pm

Alex Blekhman wrote:

> OK, I just removed `const' from the wrapped pointer
> declaration.
>
>

Alex:

I think the const must relate to the stack overflow problem mentioned in
the post by P.J Plaugher that you quoted. But I'm sure that for any
normal purpose it does not matter.

David
Tom Widmer [VC++ MVP]

2006-03-06, 3:58 am

Alex Blekhman wrote:
> Hello,
>
> I noticed that std::auto_ptr (in VC2005) declares wrapped
> object pointer like that:
>
> ...
> private:
> const _Ty *_Myptr; // the wrapped object pointer
> ...
>
> Any reason to have `const' modifier there? I looked for
> examples of auto_ptr implementation out there (including
> Scott Meyers' "More Effective C++"). None of them stores raw
> pointer with `const' modifier. So, my question is: Why
> wrapped raw pointer declared to point to const object?


I think it's because a const T will implicitly convert to const void*,
but not to void*, so it simplifies the code slightly for the case when
element_type is const. const void* is a generic pointer to hold any
non-volatile pointer, while void* is only a generic pointer for
non-volatile, non-const pointers.

Tom
Alex Blekhman

2006-03-06, 7:58 am

Tom Widmer [VC++ MVP] wrote:
>
> I think it's because a const T will implicitly convert to
> const void*, but not to void*, so it simplifies the code
> slightly for the case when element_type is const. const
> void* is a generic pointer to hold any non-volatile
> pointer, while void* is only a generic pointer for
> non-volatile, non-const pointers.


Yes, it makes sense why `const' was added for void*. I tried
my smart pointer with and without `const' with raw pointer
T* (instead of void*). It works correctly both for const and
non-const template arguments.



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com