From: Justin M. Lewis (boost_at_[hidden])
Date: 2003-04-24 13:20:44
----- Original Message -----
From: "Reece Dunn" <msclrhd_at_[hidden]>
Sent: Thursday, April 24, 2003 11:02 AM
Subject: [boost] Re: class proposal
> "Justin M. Lewis" wrote:
> > > > > > in/out seems to be used fairly commonly in COM. I'm not sure I
> >have any > > great examples off the top of my head, but I know they're
> >commonly used.
> > > I'm not a COM person, but I believe it's written in C. If so, then
> > > are correct that in/out parameters are more needed since noone would >
> >want to create a struct for each multiple return type.
> > > OTOH, C++ has templates to deal with this situation (ie
> > > so, qualifying my previous statement, in C++ I still see no need for >
> >in/out parameters.
> >I think most COM objects are written in C++. I should have been more
> >specific here, if you're looking at ActiveX objects, in/out params are
> >all over the place. Each function returns an HRESULT, iirc, any data you
> >want returned has to be returned in a param.
> The COM object interfaces are actually written in Microsoft-variant IDL,
> a similar way to CORBA. The MIDL compiler then generates C++ abstract
> classes *and* C structures, so you can use either C or C++. In fact, you
> use any supported language (Pascal, Java, etc).
> Because COM interfaces are in effect language independant, you cannot use
> the exception mechanism, so MS decided to use error code return values,
> hence the HRESULT return type.
> This is an example of a much larger problem that the parameter = in;
> = out methodology cannot cover: what if your function has more than one
> return data items? For example:
> inline void sincos( float theta, float s, float c )
> s = std::sin( theta );
> s = std::cos( theta );
> You could use the std::pair type for a return value, but this would
> complicate the code:
> std::pair< float, float > sc = sincos( 0.75 );
> std::cout << "theta = 0.75: sin = "
> << sc.first << "; cos = "
> << sc.second << "\n";
> float sinval, cosval;
> sincos( 0.75, sinval, cosval );
> std::cout << "theta = 0.75: sin = "
> << sinval << "; cos = "
> << cosval << "\n";
> I find the latter easier to read.
> The issue that this proposal is trying to solve is the modification of
> variables inside a function. Isn't this what const is for?
> inline int f( const std::list< int > & li )
> return( *li.front()); // first item
> in - by value; const reference
> out - return; reference
> in/out - reference
> IMHO, this makes more sense than having to use special wrappers that
> complicate the code and make it harder to read and maintain.
Again, the point is to make it clear at the point of invocation. Chasing
down function prototypes gets to be a pain when there are potentially 10's
of functions that the param you're looking at is passed to. So, just
marking the prototype doesn't help me while reading code that uses the
functions in question.
> If you are worried about an object being modified, use a temporary:
> std::complex< float > c1( 1.0, 2.5 );
> std::complex< float > ctemp( c1 );
> if( modifyComplex( ctemp ))
> // do something
> but this should not be needed in most cases, especially when using const
> Just my 2 cents worth.
So, it's not a fear of a param being modified, it's a solution to not
knowing what I'm looking at when I'm reading code. You may want the value
in the param to change, that may have been the original programmer's intent,
but, it's impossible for me to look at function call and tell whether or not
the params are being passed by value, reference, or const reference, all 3
look identical at the call.
> Worried what your kids see online? Protect them better with MSN 8
> Unsubscribe & other changes:
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk