Boost logo

Boost :

From: Thorsten Ottosen (nesotto_at_[hidden])
Date: 2004-01-04 01:49:58


Hi Dave,

I can see I'm beginning to **** you off :-) When things get heated, we all
tend to see
the world the way we like it.

"David B. Held" <dheld_at_[hidden]> wrote in message
news:bt89ob$qbg$1_at_sea.gmane.org...
> "Thorsten Ottosen" <nesotto_at_[hidden]> wrote in message
> news:bt8513$l3a$1_at_sea.gmane.org...
> > "David B. Held" <dheld_at_[hidden]> wrote in message
> > news:bt827b$hvp$1_at_sea.gmane.org...
> > > [...]
> > > Is this code not const-correct?
> >
> > I don't see your point, but yes.
>
> I don't understand your answer. Yes it is correct, or yes it isn't
> correct?

The most important application of propagating constness is when storing an
object by
pointer in a class:

class X
{
    smart_ptr<My_polymorhic_type> p_;
public:
    int bar() const
   {
       return p_->this_is_also_a_const_function(); // compile time error if
not
    }
};

This is the motivating examlple that I have referred to all the time. I'm
sorry I didn't
brought it to your attention earlier. This is what I mean by bypassing the
type system.

You and others apparently want to call non-const functions on 'p_'. Fine,
although a
bit strange.(It is strange because one could not do it if one stored a
string member.)
And the solution would be to make 'p_' mutable. This is what mutable is
there for afterall.

> > If we have a const member functions I want (and many others)
> > constness to propagate to members pointers or not. If an
> > argument is const, I don't wan't to change the argument <g>.
>
> All I was saying is that a const member function can call functions
> that are non-const and still be const-correct. I really don't know
> what you are saying.

Not in the example I give above. The fact that one can pass a non-const
object to function
is besides the point; one do so for a reason.

> > Instead of thinking about syntax, think about usefulness. I have
> > repeatedly asked for real examples where the current behavior
> > is really needed and none has come up with them.
>
> What about Peter Dimov's example? All you said was: "I would do
> it differently." Well, you can do just about anything differently in C++,
> so why should we come up with any examples? The fact is, this is
> an extremely common idiom:
>
> void foo(shared_ptr<X> const& p)
> {
> p->nonConst();
> }
>
> I know, because I've done it hundreds of times. And yes, I do want
> the & to be const, because I don't want to accidentally reset() the
> pointer in the function. *That's* const-correctness.

Assuming my suggestion, how would you reset the pointer? You can't
assign to your argument. You cannot call reset() because it is non-const.

You would need in order to call the function either a cast or a new member
which returns a mutable pointer,
but that should surely be *easy* to provide.

I don't know why Peter Dimov never responded to my mail back then, but as
you can see
I said, why could the function not look like this:

void f( T& t )
{
   t.nonConst();
}

?

> > [...]
> > 1) Many people don't like that behavior
>
> So far, you're the only one here who's said so. If there's so many
> other people who don't like that behavior, I wonder where they are?
> Mr. Wallin argues for deep const for deep copy, but I don't see him
> saying anything about shallow copy pointers.

Did you read the entire thread? Peter Koch Larsen and Nikolai Pretzell
backed me up back then.

You're right that deep copy pointers seem to have propagation of constness.
Kevlin Henney's cloned_ptr has it.

> > 2) Those people can't get what they want easily
>
> Sure they can't. You still haven't shown how smart_ptr<T const>
> does *not* give you what you want. You said something about
> "unconditional const", but that didn't parse at all. Tell me exactly
> which parts of the smart_ptr<> (or shared_ptr<>, since it relies
> on the same syntax) interface are unsatisfactory under these
> conditions.

In my example above shared_ptr<const T> will not give me what I want.
I've stated this again and again.

> > 3) If the design is changed, those who favor the current design
> > can get what they want easily
>
> No they can't. They have to use const_cast<> and/or mutable to
> get what they want. On the other hand, using the current design,
> users only need to use smart_ptr<T const>, which requires no
> ugly and potentially dangerous casts or other code changes.

see previuos comment.

> > 4) The property that const smart_ptr<T> must absolutely be equal
> > to T* const has not been justified
>
> A) When writing a drop-in replacement for an existing facility, it is
> best to emulate that facility as much as is reasonable.

The fact that shared_ptr has been designed to be a drop-in replacement
does not justify why a shared_ptr should have this property. Also, you can't
just
do a search and replace on your code and change all T* to shared_ptr<T>.
So why is drop-in replacement important?

>B) It allows
> for proper const-correctness without ugly hacks. What has not been
> explained is how const_cast<> is *not* a hack, but
> smart_ptr<T const> *is*. That's exactly backwards in my world.

As said, there is not need for the cast.

> > in any way; It seems that the use for it is seriousely limited
>
> If you consider passing a pointer by const& a "seriously limited"
> application.

Again, I would alsway pass my raw pointer by value. The fact that
you need to use a reference to prohibit a ref-count updates really shows
that the drop-in replacement is not possible.

> > If you add to this that smart pointers is going to be used in almost
> > any future C++ program, it should be serving most people needs.
>
> Considering how long shared_ptr<> has been around, the number
> of programs it's been used in, and that fact that the only real gripe
> with the constness of shared_ptr is in the copy cost for shared_ptr<T>
> to shared_ptr<T const>, I'd say that it is serving most people's needs
> quite well. In fact, you have not demonstrated the contrary.

Again, my example above shows it.

> > I have no intension to prohibit those who wan't to bypass the type
> > system, but I would appreciate that I can use it if I wan't.
>
> Umm...*you* are the one suggesting that people use const_cast<>
> so that deep-const semantics can be the default! How on earth can
> you pretend that you are using the type system and everyone else
> is "bypassing" it?? This is sheer madness!

I'm sorry to hear that. :-) I hope I've put some of the maddness away in
this mail.

br

Thorsten


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk