Boost logo

Boost :

From: Justin M. Lewis (boost_at_[hidden])
Date: 2003-05-03 21:41:23

----- Original Message -----
From: "Noel Yap" <Noel.Yap_at_[hidden]>
To: "Boost mailing list" <boost_at_[hidden]>
Sent: Saturday, May 03, 2003 5:37 PM
Subject: Re: [boost] Re: in/out parameters, codingstylesandmaintenance

> "Justin M. Lewis" wrote:
> > > I haven't seen you address the issue of in parameters. I'm assuming
> > > want something like:
> > >
> > > f( in( t ) );
> > >
> > > If so, why not one of:
> > >
> >
> > Yes, I have been thinking about in only params, as a case where you're
> > either giving up ownership of the data, or destroying the data, which
may be
> > the most common instance of these types of data. I just didn't want to
> > propose anymore out and in_out are already getting quite a bit of
> > as it is. And, again, it makes the intent 100% clear, that, hey, after
> > call, I shouldn't go on accessing t like I own it. Basically, in would
> > there are no guarantees about the state of teh param passed to the
> Then why not one of:
> void f( std::auto_ptr< T > t_ ); // passes ownership of pointer to f
> void f( boost::dumb_ptr< T const > t_ ); // caller keeps ownership of
> t_

Again, why use pointers where we can use references? And, again, the intent
is 100% clear with a c_in parameter, where it's not with a pointer.

> > > In parameter:
> > >
> > > void f( boost::dumb_ptr< T const > t_ ); // look Ma, no dynamic
> > > allocation required
> > >
> >
> > It's still not clear that you didn't just want a pointer passed to the
> > function.
> The point is that the function cannot operate on t_ so, therefore, t_ is
> an in parameter.

we're not in sync here on what an in param is. To me an in param would be
where the caller is giving up ownership, so the called function is going to
either destroy the passed in data, or free it or, keep it internally to be
freed by that object later.

> > > Out parameter:
> > >
> > > boost::dumb_ptr< T > f(); // again, no dynamic allocation required
> > >
> > > In/Out parameter:
> > >
> > > void f( boost::dumb_ptr< T > t );
> > >
> > > BTW, I don't see why shy away from pointers. Is it only raw pointers
> > > you don't like, or also wrapped pointers? Why? Why don't you
> > > references to be pointers that are implicitly dereferenced (a sort of
> > > built-in pointer wrapper, if you will)?
> >
> > references are safer in that they tend to mean, this data isn't
> > allocated,
> Huh?
> void f( T const& t_ );
> T* t = new T();
> f( *t );
> > you're not referencing and dereferencing.

You sure are dereferencing that pointer there. Not at the call, but inside
the function you certainly access the data inside that pointer.

> Like I said before, references are implicitly dereferenced pointers.

I think Floris responded to this claim a few times. I'm with him.

> > For example, you don't
> > see people testing like this
> >
> > void func(T &t)
> > {
> > assert(&t != NULL);
> > }
> I haven't tried it so I don't know if it's possible, but it may be
> possible to have a CanBeNull policy on the boost::dumb_ptr<>.
> Also, what if you /want/ them to be able to pass in NULL.

If you want to be able to pass NULL do something like

void myfunc(c_in_out<CObj *> x);

Now you have a function that is actually dealing with pointers, not just
using them as a subsitute for references.

> Also, isn't the above something you don't want to do since it's not
> obvious from the call site whether it's an in parameter, an out
> parameter, or an in/out parameter?
> > because there's an assumption that references are really meant to make
> > passing large data cheap, without having to resort to pointer notation.
> >
> > I
> > guess it makes it clear, that, if you're passing me a reference to data,
> > have no intention of checking to make sure that reference is pointed to
> > data, that's your job as the caller. Anyway, the less you use pointers
> > altogether, the better. The less likely you are to have memory leaks,
> > memory faults.
> OK. I think I see:
> - you want to guarantee that the objects passed into the function aren't
> null so you're stuck with using references.
> - sticking with references only doesn't allow you to differentiate among
> in parameters and in/out parameters at the call site.
> - out parameters should be returned either by value or by (smart or raw)
> pointer. The function writer should be able to guarantee a non-NULL
> return value if it's necessary so the NULL argument doesn't hold here.

I like the safety of references over pointers. Like I said, in general use,
when you have references you tend to not do as much data allocation and
deallocation. You don't need to think about the case where someone passes
you a bogus pointer, because people tend to be passing non-pointer data.
So, anyone who IS passing allocated data gets stuck with taking care of
making sure the data is allocated and pointed properly before passing. To
me it says, this function only deals with real data, it doesn't handle cases
where this data does not exist, so you can avoid all of the assert(ptr !=
NULL); all teh way down the call chain from there, since, if you were going
to do it right, every function that takes a pointer as a param would check
to make sure that ptr is not null, with at least an assert.

> Given all of the above, I think you really want to champion c_in and
> c_in_out rather than c_out and c_in_out. What do you think?

I do really like the idea of a c_in as well. As it happened though, my
first use was for an out only param, and originally when I started this, I
had no concept of out, in_out, and in. It was originally just called
retval, after talking with others it was split into c_out and c_in_out,
then, later after that, after I brought the idea here, someone else asked
about in params, the type of in params I've been talking about, where the ca
ller is giving up ownership of the data. But, yes, ultimately I would want
to see a c_in in this library.

> Noel
> _______________________________________________
> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at