[omniORB] sequence<string>::operator[]
Bruce Visscher
visschb@rjrt.com
Wed, 12 Apr 2000 16:22:01 -0400
Sorry to reply to my own post, but I have another question about this.
Apparently, the operator[] for sequences of strings worked under 2.7.1 on Compaq
C++ 5.6/OpenVMS VAX. I am having to work around this for 2.8.0 by using the
getbuf/freebuf interface (ick).
Under 2.7.1, sequences of strings were a typedef as CORBA::String_member. Also,
the implementation of CORBA::String_member was much simpler (just a pointer, no
reference, no flag). What problems or enhancements was the new implementation
intended to address?
Bruce Visscher wrote:
>
> 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