[omniORB] sequence<string>::operator[]

Bruce Visscher visschb@rjrt.com
Wed, 12 Apr 2000 14:33:57 -0400


Hello all,

The code at the end of this message was adapted from [Henning & Vinoski], page
183.  I added the "Const is broken" test.

When I compile and run this on OpenVMS Alpha using Compaq C++ 6.2 and omniORB
2.8.0, I get:

myseq[0] = "first"
myseq[1] = "second"
myseq[2] = "third"
myseq[3] = "fourth"

myseq[0] = "first"
myseq[1] = "second element"
myseq[2] = "third"
myseq[3] = "4th"
myseq[4] = "5th"

myseq[0] = "Const is broken"
myseq[1] = "second element"
myseq[2] = "third"
myseq[3] = "4th"
myseq[4] = "5th"

On OpenVMS VAX using Compaq C++ 5.6C and either omniORB 2.8.0 or omniORB 3.0 I
get:

myseq[0] = ""
myseq[1] = ""
myseq[2] = ""
myseq[3] = ""

myseq[0] = ""
myseq[1] = ""
myseq[2] = ""
myseq[3] = ""
myseq[4] = ""

myseq[0] = ""
myseq[1] = ""
myseq[2] = ""
myseq[3] = ""
myseq[4] = ""

I'm actually not too concerned about the const-correctness problem on Alpha.
This code is relying on an implementation artifact (CORBA::String_member) rather
than something in the CORBA standard.  BTW, since String_member is non-standard
should this even be in the CORBA namespace?   In any case, I think the problem
here is the compiler is being "too" agressive with optimization (but don't know
that it's wrong).

I believe the problem with the 5.6 compiler on the VAX is that the
implementation of _CORBA_Sequence__String::operator[] (non-const) relies on a
compiler optimization being performed:

  inline ElemT operator[] (_CORBA_ULong i) {
    if( i >= pd_len )  _CORBA_bound_check_error();
    return ElemT(pd_data[i],pd_rel);
  }

I believe that this is another form of copy initialization which is defined as
performing a copy which the compiler is allowed (but not required) to optimize
away.  If the copy is performed then we get an independent String_member and the
assignment modifies a temporary that no longer has any relation to the sequence
member.

Is this analysis correct?  Do other platforms experience this problem?

---------------------------------- strseq.idl ----------------------------------
typedef sequence<string> StrSeq;
---------------------------------- strseq.idl ----------------------------------
wpsys2[.STRINGSEQ]> @home:outputforcut "strseq.cc"
---------------------------------- strseq.cc -----------------------------------
#include <iostream>
#include "StrSeq.hh"

#if defined(__DECCXX) && (__DECCXX_VER < 60000000)
#define std
#endif

int main() {
    char const* values[] = { "first", "second", "third", "fourth" };

    StrSeq myseq;

    // Create four empty strings
    myseq.length(4);
    {   //  redundant scope for broken compilers
        for (CORBA::ULong i = 0; i < myseq.length(); i++) {
            CORBA::String_member tmp(myseq[i]);
            tmp = values[i];   //       Deep copy
        }
    }

    //  Print current copy.
    {   //  redundant scope for broken compilers
        for (CORBA::ULong i = 0; i < myseq.length(); i++)
            std::cout << "myseq[" << i << "] = \"" << myseq[i] << "\"" << std::e
ndl;
    }
    std::cout << std::endl;

    // Change the second element (deallocates "second")
    myseq[1] = CORBA::string_dup("second element");

    // Truncate to three elements
    myseq.length(3);                // Deallocates "fourth"

    // Grow to five elements (add two empty strings)
    myseq.length(5);

    // Initialize appnded elements
    myseq[3] = CORBA::string_dup("4th");
    myseq[4] = CORBA::string_dup("5th");

    // Print contents once more
    {   //  redundant scope for broken compilers
    for (CORBA::ULong i = 0; i < myseq.length(); i++)
        std::cout << "myseq[" << i << "] = \"" << myseq[i] << "\"" << std::endl;
    }
    std::cout << std::endl;

    StrSeq const& constref(myseq);
    CORBA::String_member x=constref[0];
    x="Const is broken";
    {   //  redundant scope for broken compilers
    for (CORBA::ULong i = 0; i < myseq.length(); i++)
        std::cout << "myseq[" << i << "] = \"" << myseq[i] << "\"" << std::endl;
    }
}
---------------------------------- strseq.cc -----------------------------------

Bruce Visscher