CORBA style was: [omniORB] CORBA::string_alloc(len) problem

David Riddoch djr@uk.research.att.com
Fri, 16 Jul 1999 14:13:56 +0100 (GMT)


On 16 Jul 1999, Bjorn Wennberg wrote:

> David Riddoch <djr@uk.research.att.com> writes:
> 
> > On 16 Jul 1999, Bjorn Wennberg wrote:
> > 
> > > I'm just curious about this :-)
> > > 
> > > As far as I'm able to understand the behaviour of string_alloc - it returns
> > > a character pointer not a new String_var class?
> > > 
> > > Thus the assignment would be correct without temporary copying the String_var:
> > > 
> > > 1. String_var SomeString(CORBA::string_alloc(100));
> > > 2. String_var SomeString(new char[100]);
> > > 3. String_var SomeString = CORBA::string_alloc(1000);
> > > Number 1 and 2 are equal and uses the ctor:
> > > String_var::String_var(char *p) { _data = p; }
> > > Number 3 might use either the ctor or the assignment operator, which are equal:
> > > String_var::operator = (char *p) { if (_data) string_free(_data); _data = p; }
> > 
> > No - the right hand side is a String_var, not a char*, so we use:
> > 
> > String_var::operator = (String_var&)
> > 
> > And thus we *copy* the string rather than consume it.
> 
> I don't think so. What is the point with different ctor's if you can't
> use them?
> One of the ctor takes a 'char *' as parameter - and according to my 
> debugger,
> it uses the ctor 'String_var::String_var(char *p)' when constructing
> the variable.

Yes, because your compiler is using an optimisation.  In the ARM, section
12.6.1 it says that initialisation of the form:

T x = a;

means "construct the value specified in a temporary object, and then copy
it to the variable being initialised using the copy constructor."

Thus we construct a temporary of type 'T' from 'a', and initialise 'x'
with the temporary, using the copy constructor.  In our case we have to
construct a temporary String_var using the char* constructor, then assign 
that temporary to SomeString using the copy constructor.

The ARM goes on to say that a decent compiler will optimise this to be:

T x(a);

However, this is not required, and doesn't happen on the VAX.

The reason that it fails is really because if you initialise a String_var
with a char* which has not been initialised, then the String_var is not
really properly initialised.  Thus the temporary that is created is never
properly initialised, and attempting to copy it has bad consequences.
This is very similar to the original problem, where String_var::operator[]
assumed that the value was properly initialised, but it was not.


> If the right-hand-side expression (CORBA::string_alloc(100)) returns a
> 'char *'
> why shall it not use the ctor that takes a 'char *'?

Because the standard says we should construct a temporary and use the copy
constructor (unless optimised away...).


Hope thats a bit clearer now!
David