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

Bruce Visscher visschb@rjrt.com
Fri, 16 Jul 1999 11:10:02 -0400



David Riddoch wrote:
> 
> On 16 Jul 1999, Bjorn Wennberg wrote:
> 
> > Back to the example of accessing the elements of the String_var;
> > What is wrong with doing:
> > String_var SomeString = CORBA::string_alloc(100);
> 
> The above line is the problem.  The c++ spec says that this is equiv to
> 
> String_var SomeString;
> {
>   String_var _tmp(CORBA::string_alloc(100));
>   SomeString = _tmp;
> }
> 

Well, actually this isn't quite correct either.  Copy iniitialization
doesn't invoke the assignment operator.  It invokes the converting
constructor then the copy constructor (followed by the destructor of the
temporary).  The problem is that this is difficult to express in code:

  CORBA::String_var
SomeString(CORBA::String_var(CORBA::string_alloc(100)));

> Thus we attempt to copy a string which is uninitialised.  In the case of
> omniORB it will have been initialised to the empty string -- but this just
> means we will end up with a buffer of length 1 instead of 101 as intended.
> Now most compilers optimise away _tmp and the assignment to give what
> you'd expect, but a few (eg. on VAX) don't.
> 

I see that this has changed (way back at 2.7.0) so my statement that the
copy constructor would do a strlen on uninitialized memory was wrong. 
Of course this is still problematic, since the programmer will likely
assume that SomeString.length() is 101.

> Better would be the following line, and then the rest of your example is
> okay.
> 
> String_var SomeString(CORBA::string_alloc(100));
> 

To get back to Mark Landy's comments:

> Is there any wonder why developers swear off C++ and CORBA for more
> accessible technologies like Java and VB? You'd need a friggin' master's
> degree in CS to understand this discussion. I've got one and it still
> doesn't make much sense. What ever happened to the art of writing code that
> others can read (and compilers can translate)?

I was actually hesitant to post the message that started all of this
fearing exactly this reaction (no offense intended; none taken).  I
don't have an MS in CS.  I only stumbled on this in attempting to port
omniORB to the VAX platform some time ago.  It was a difficult bug for
me to find precisely because I tended to think of direct and copy
initialization to be the same (see below).

Actually, I agree this is needlessly complicated, but I'm not sure who
to blame.  

The ISO standard?

Personally, I find that even experienced C++ developers don't understand
the subtle difference between copy and direct initialization syntax. 
However, given the language definition, I think this understanding is in
order.  After all, this hasn't changed since the ARM.

The CORBA C++ mapping?

Personally, I have never been a fan of CORBA::String_var (I think it's
bad form to have constructor overloads that differ only in const that
have completely different semantics).  Had they had a std::string type
available to use perhaps they would have done things differently.  I use
std::string in my applications wherever possible.

The omniORB implementation?

Douglas Kosovic was arguing for a "safer" implementation.  In fact, to
solve the "copy initialization problem" you would need to do a memset to
some non-zero value rather than 0 before setting the last char to 0. 
But I agree with Steven Coy that if omniORB did something like this that
it might be costly in terms of performance and that doing this would
only encourage the writing of non-portable code.

If you want a simple guideline, it would be something like:

	Prefer direct initialization (i.e., the "function call
	looking" initialization).

Direct initialization has more straight forward semantics.  But, the
bottom line is that there *is* a difference.  If you have a standards
conforming compiler and library you *have* to use direct initiailization
for std::auto_ptr, for example.

See http://www.cntc.com/resources/gotw001.html,
http://www.cntc.com/resources/gotw036.html and section 8.5 of the ISO
standard (I'll assume readers know where to find the CORBA::String_var
definition:-)).

Bruce