[omniORB] Array Return Values and _var's

Sai-Lai Lo s.lo@uk.research.att.com
Mon, 30 Jul 2001 10:57:15 -0000


Ken,

This is one of the annoyance of MSVC++ that I hope will go away. MSVC++ is
confused by the presence of 3 operators in an Array _var type:


  inline T& operator[] (_CORBA_ULong index) {
    return *(pd_data + index);
  }
  inline const T& operator[] (_CORBA_ULong index) const {
    return *((const T*) (pd_data + index));
  }
  inline operator T* () const { return pd_data; }

All other compilers seems to have no problem with this. Anyway, just me
moaning about MSVC++
does not solve the problem.

Of the 3 operators, the T* operator is the only 1 not specified in the CORBA
spec. Therefore, in order to be fully compilance, you shouldn't use 2) in
your solution!

The reason I have the T* operator is that in the earlier spec., one is
supposed to be able to pass a _var type as an IN argument to an operation
and expect the right conversion operator to be invoked. Seems that no one
has implemented this correctly (except us may be) and so the rule has
changed. Now if one is to pass a _var type as an IN argument, one should
call the in() member of the var type explicitly.

In a way, the T* operator is now obsoluted and may be we should consider
removing it.
You can try this yourselves by editing
<top>/include/omniORB3/templatedecls.h and remove the T* operator in
_CORBA_Array_Var.

Sai-Lai

----- Original Message -----
From: "Ken Feuerman" <kfeuerma@adobe.com>
To: <omniorb-list@uk.research.att.com>
Sent: Thursday, July 26, 2001 4:57 PM
Subject: [omniORB] Array Return Values and _var's


> Suppose I have the following IDL:
>
>      interface TestObj
>      {
>          typedef long Larr[3];
>          Larr Method(in long param);
>      };
>
> I would like to implement the Method() as follows:
>
>      TestObj::Larr_slice* Method(CORBA::Long param)
>      {
>          TestObj::Larr_var result = TestObj::Larr_alloc();
>          for (int i = 0; i < 3; ++i)
>              result[i] = param;  // (***)
>          return result._retn();
>      }
>
> The problem is that when compiling under MSVC 6.0 on Win2K, the line
marked
> (***) is flagged with the following compiler error:
>
>      error C2666: '[]' : 3 overloads have similar conversions
>
> I've discovered three possible workarounds, each of which have their
drawbacks:
>
> 1.  Declare result to be TestObj::Larr_slice* instead of
TestObj::Larr_var,
> and return result directly at the end.  The drawback of course is that if
I
> throw out of this method, I leak.  (I might throw because someday the
> Method will be doing actual useful stuff between Larr_alloc() and
_retn().)
>
> 2.  Replace the (***) line with
>              ((TestObj::Larr_slice*)result)[i] = param;
> The drawback is an ugly looking cast that obfuscates.  Furthermore, I'm
> relying on the "operator TestObj::Larr_slice*()" conversion operator that
> happens to be defined in the omniidl-generated stubs; is this operator
part
> of the CORBA C++ mapping?
>
> 3.  Use ORBacus instead, which doesn't seem to have this problem.  The
> drawback is of course that I wouldn't be using omniORB!
>
> By the way, I happen to be using the July 11 snapshot of omniORB4, in case
> that matters.  Am I trying to do the Right Thing regarding the memory
> management?  Is this an omniORB (or, to be fair, an MSVC 6.0) bug?  Of all
> the workarounds, I'm leaning toward 2, provided I can be sure of using the
> correct operator to get at the underlying array slice pointer.
>
> Thanks for your advice!
>
> --Ken Feuerman.
> Adobe Systems, Inc.
>
>
>