Issue 3298: Problem with OBV_ valuetype class constructor (cxx_revision) Source: Floorboard Software (Mr. Jonathan Biggar, jon(at)floorboard.com) Nature: Uncategorized Issue Severity: Summary: The CORBA 2.3.1 specification does not cover the case of code generation for the OBV_ class constructor for a valuetype that inherits from another concrete valuetype: // IDL valuetype A { octet o1; }; valuetype B : A { octet o2; }; The generated OBV constructor for class B needs to take both o1 and o2 arguments, so it should look like this: // C++ class OBV_B { ... protected: ... OBV_B(Octet init_o1, Octet init_o2) }; Proposal: Change the second paragraph of 1.17.2 to read: "For the same reasons, a C++ OBV_ class defines a protected default constructor, a protected constructor that takes an initializer for each valuetype data member, and a protected default constructor. The parameters of the constructor that takes an initializer for each member appear in the same order as the data members appear, top to bottom, in the IDL valuetype definition, regardless of whether they are public or private. If the valuetype inherits from a concrete valuetype, then parameters for the data members of the inherited valuetype appear first. All parameters for the member initializer constructor follow the C++ mapping parameter passing rules for in arguments of their respective types." Resolution: see below Revised Text: Change the second paragraph of 1.17.2 to read: "For the same reasons, a C++ OBV_ class defines a protected default constructor, a pro-tected constructor that takes an initializer for each valuetype data member, and a pro-tected destructor. The parameters of the constructor that takes an initializer for each member appear in the same order as the data members appear, top to bottom, in the IDL valuetype definition, regardless of whether they are public or private. If the valuetype inherits from a concrete valuetype, then parameters for the data members of the inherited valuetype appear first. All parameters for the member initializer constructor follow the C++ mapping parameter passing rules for in arguments of their respective types. For value-types that have no operations other than factory initializers, the same constructors and destructors are generated, but with public access so that they can be called directly by application code." Actions taken: February 6, 2000: received issue October 3, 2001: closed issue Discussion: End of Annotations:===== From: Paul Kyzivat To: "'issues@omg.org'" Cc: "C++ RTF (E-mail)" Subject: Object Reference insertion/extration to Any Date: Thu, 27 Jan 2000 16:35:57 -0500 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2448.0) Content-Type: text/plain; charset="iso-8859-1" X-UIDL: F^&e9;lpd9YI9e97RTd9 I believe the specification for insertion of object references to Anys is somewhat ambiguous. And, if it is intended to be as I think, it may also be less than ideal. Consider the following idl: interface B {...}; interface D : B {...}; And then consider the following code: D_ptr d; // initialize this to non-null value somehow B_ptr b = B::_narrow(d); Any ab; ab <<= b; Any ad; ad <<= d; // ... B_ptr b_val; if (ab>>=b_val) { /* do stuff with b_val */ }; // 1 if (ad>>=b_val) { /* do stuff with b_val */ }; // 2 D_ptr d_val; if (ab>>=d_val) { /* do stuff with d_val */ }; // 3 if (ad>>=d_val) { /* do stuff with d_val */ }; // 4 >From what I can see of the spec, it is a bit unclear about whether then insertion of an object should use the static type or the dynamic type of the object to initialize the typecode. Simplicity and consistency with other related operations suggests that it should use the static type. That is what we currently do, and a quick test of ORBIX 2000 seems to tell me it does it that way too. With that interpretation, 1&4 will work, while 2&3 will fail. Nobody should be surprised that 3 fails, but it is inconvenient that 2 doesn't work. If insertion used the dynamic type of its argument, then 1&2 would work, while 3&4 would fail. To get reasonable behavior when derived types might be present, (and how often can you be certain they cannot?) it seems that one should almost never use type specific object extraction. Instead, one must do something like: Object_var o; B_var bv; if (ad>>=to_object(o._out()) && !CORBA::is_nil(bv = B::_narrow(o))) { // do stuff with bv }; This is unfortunately a bit inconvenient. So, is there any text in the spec that says, when inserting an object reference type into an any, if the repository id in the typecode should be the static type of the inserted argument or the dynamic type of the value of the argument? If not, I think we need to add some text. ____________________ Paul Kyzivat Rogue Wave Software paulk@roguewave.com Sender: jbiggar@corvette.floorboard.com Message-ID: <3890CB37.E3996125@floorboard.com> Date: Thu, 27 Jan 2000 14:48:23 -0800 From: Jonathan Biggar X-Mailer: Mozilla 4.7 [en] (X11; U; SunOS 5.6 sun4u) X-Accept-Language: en MIME-Version: 1.0 To: Paul Kyzivat CC: "C++ RTF (E-mail)" Subject: Re: Object Reference insertion/extration to Any References: <9B164B713EE9D211B6DC0090273CEEA9140321@bos1.noblenet.com> Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii X-UIDL: UpGe9Y@Wd9\\+!!MXF!! Paul Kyzivat wrote: > From what I can see of the spec, it is a bit unclear about whether then > insertion of an object should use the static type or the dynamic type of the > object to initialize the typecode. Simplicity and consistency with other > related operations suggests that it should use the static type. That is what > we currently do, and a quick test of ORBIX 2000 seems to tell me it does it > that way too. I agree that the Any inserter must use the static type, not the dynamic one for several reasons: 1. Otherwise, why have more than 'operator<<(CORBA::Any &, CORBA::Object_ptr)'? 2. It would violate the principal of least suprise: B_ptr myb; A_ptr mya = myb; Any myany; myany <<= &mya; // OK assert(myany >>= mya); // fails! 3. It pretty much renders all any extraction operators except to_object useless. If you think more text is necessary, feel free to propose some. :-) -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org From: Paul Kyzivat To: "C++ RTF (E-mail)" Subject: RE: Object Reference insertion/extration to Any Date: Thu, 27 Jan 2000 18:25:24 -0500 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2448.0) Content-Type: text/plain; charset="iso-8859-1" X-UIDL: '^(e9`bI!!^7ld9W8m!! Jon, I agree that consistency seems to demand using the static type. I floated this issue for two reasons: - just to check if anybody already implements insertion using the dynamic type - because the static extraction seems so useless. I wanted to initiate some discussion about this. Am I missing something? Is it really useful in the current form? After achieving those goals I will be happy to propose some words. Paul > -----Original Message----- > From: Jonathan Biggar [mailto:jon@floorboard.com] > Sent: Thursday, January 27, 2000 5:48 PM > To: Paul Kyzivat > Cc: C++ RTF (E-mail) > Subject: Re: Object Reference insertion/extration to Any > > > Paul Kyzivat wrote: > > > From what I can see of the spec, it is a bit unclear about > whether then > > insertion of an object should use the static type or the > dynamic type of the > > object to initialize the typecode. Simplicity and > consistency with other > > related operations suggests that it should use the static > type. That is what > > we currently do, and a quick test of ORBIX 2000 seems to > tell me it does it > > that way too. > > I agree that the Any inserter must use the static type, not > the dynamic > one for several reasons: > > 1. Otherwise, why have more than 'operator<<(CORBA::Any &, > CORBA::Object_ptr)'? > > 2. It would violate the principal of least suprise: > > B_ptr myb; > A_ptr mya = myb; > Any myany; > > myany <<= &mya; // OK > assert(myany >>= mya); // fails! > > 3. It pretty much renders all any extraction operators > except to_object > useless. > > If you think more text is necessary, feel free to propose some. :-) > > -- > Jon Biggar > Floorboard Software > jon@floorboard.com > jon@biggar.org > Date: Fri, 28 Jan 2000 10:44:31 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: Paul Kyzivat , "C++ RTF (E-mail)" Subject: Re: Object Reference insertion/extration to Any In-Reply-To: <3890CB37.E3996125@floorboard.com> Message-ID: Organization: Object Oriented Concepts MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-UIDL: 7'Pd9#?L!!PO\d9HH:!! On Thu, 27 Jan 2000, Jonathan Biggar wrote: > I agree that the Any inserter must use the static type, not the dynamic > one for several reasons: I agree. Given where we are, that's the only thing that makes sense. Cheers, Michi. X-Sender: vinoski@mail.boston.amer.iona.com X-Mailer: QUALCOMM Windows Eudora Pro Version 4.1 Date: Thu, 27 Jan 2000 19:44:50 -0500 To: Paul Kyzivat From: Steve Vinoski Subject: Re: Object Reference insertion/extration to Any Cc: "C++ RTF (E-mail)" In-Reply-To: <9B164B713EE9D211B6DC0090273CEEA9140321@bos1.noblenet.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-UIDL: W3Qd9Z!ad99$Ud9~U?e9 At 04:35 PM 1/27/00 -0500, Paul Kyzivat wrote: > D_ptr d; // initialize this to non-null value somehow > B_ptr b = B::_narrow(d); > Any ab; > ab <<= b; > Any ad; > ad <<= d; > // ... > B_ptr b_val; > if (ab>>=b_val) { /* do stuff with b_val */ }; // 1 > if (ad>>=b_val) { /* do stuff with b_val */ }; // 2 Funny, I just answered this question for someone else today. Extraction is based entirely on TypeCode::equivalent. Despite the inheritance relationship, a D reference is not type-equivalent to a B reference, so 2 can't work. Supporting this would be possible by building the right information into client-side generated code, but is generally difficult because it would require IFR lookup in some cases. If a process containing only stubs for Base received an Any holding a Derived, and the process attempted extraction as a Base, you'd have to go to the IFR to figure out if Derived is derived from Base. Implicit IFR lookups inside the ORB are always to be avoided. >>From what I can see of the spec, it is a bit unclear about whether then >insertion of an object should use the static type or the dynamic type of the >object to initialize the typecode. Simplicity and consistency with other >related operations suggests that it should use the static type. That is what >we currently do, and a quick test of ORBIX 2000 seems to tell me it does it >that way too. It's always been based on static type, but if you think additional explanation is required, please propose the new text. And the most important question of all: how do you have a copy of Orbix 2000? --steve Date: Fri, 28 Jan 2000 11:05:27 +1000 (EST) From: Michi Henning To: Paul Kyzivat cc: "C++ RTF (E-mail)" Subject: RE: Object Reference insertion/extration to Any In-Reply-To: <9B164B713EE9D211B6DC0090273CEEA9140323@bos1.noblenet.com> Message-ID: Organization: Object Oriented Concepts MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-UIDL: U/Q!!f^^!!h'Ce9#_""! On Thu, 27 Jan 2000, Paul Kyzivat wrote: > - because the static extraction seems so useless. > I wanted to initiate some discussion about this. > Am I missing something? Is it really useful in the current form? The problem with dynamic extraction is that the ORB may not have the stubs for the dynamic type linked in. That means that dynamic extraction would be impossible for some types and possible for others (but only at the cost of keeping global knowledge of the types around, which we decided is a no-no). I don't see any way to get dynamic extraction to work. This topic is really very similar to the UnknownUserException thing. In both cases, lack of static type knowledge drives the solution. I think that the any extraction/insertion got it right. Cheers, Michi. From: Paul Kyzivat To: "'Michi Henning'" , Paul Kyzivat Cc: "C++ RTF (E-mail)" Subject: RE: Object Reference insertion/extration to Any Date: Fri, 28 Jan 2000 08:49:40 -0500 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2448.0) Content-Type: text/plain; charset="iso-8859-1" X-UIDL: WI-!!-1i!!iUp!!e;Z!! > From: Michi Henning [mailto:michi@ooc.com.au] > The problem with dynamic extraction is that the ORB may not > have the stubs > for the dynamic type linked in. That means that dynamic > extraction would > be impossible for some types and possible for others (but > only at the cost > of keeping global knowledge of the types around, which we decided is > a > no-no). I don't see any way to get dynamic extraction to work. Dynamic extraction could work without reference to an IR by simply attempting to narrow the object reference to the target type. But there are problems with this: - it can be expensive - it may be hard to do and still have the any retain ownership of the reference it hands out - the compatibility check in effect ignores the repid in the typecode > > This topic is really very similar to the UnknownUserException thing. > In both cases, lack of static type knowledge drives the solution. > I think that the any extraction/insertion got it right. Yes, it is quite similar. I think that is what initiated me thinking about the problem. The static type is clearly the preferred technique from an implementatability perspective. However it doesn't seem to be very desireable from a usability perspective. If I depend on extraction by static type, my code will break whenever presented with a derived type. It is hard to imagine a case when this is the right thing to do. So, for a robust application I think I am forced to always do extraction using to_object and then narrow. If I had it to do over, I think maybe I would only provide insertion and extraction of Object. Then the to_object helper would not be necessary and extraction to object would not need to cause a duplicate. It would then be clear that to get anything other than Object a narrow would be required. But, since doing it over would be disruptive (to us as much as anyone else), I am content to leave things as they are. But I will work on some clarifying words, and perhaps an example. (But I think I will wait for an issue number first.) Paul