Issue 5467: How does DynValue handle derived valuetypes? (corba-rtf) Source: Floorboard Software (Mr. Jonathan Biggar, jon(at)floorboard.com) Nature: Uncategorized Issue Severity: Summary: I just noticed that the description of DynValue is totally silent on the issue of derived valuetypes. Here's an example to set things up: // IDL valuetype A { public short s; }; valuetype B { public long l; }; struct S { A an_a; }; // C++ DynamicAny::DynFactory df = ...; B *b = ...; S my_s; CORBA::Any my_any; s.an_a = b; my_any <<= s; DynamicAny::DynAny_var da = df->create_dyn_any(my_any); DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(da); ds->seek(0); da = ds->current_component(); DynamicAny::DynValue_var dv = DynamicAny::DynValue::_narrow(da); CORBA::TypeCode_var tc = dv->type(); cout << tc->id() << endl; ----------- Now some questions: 1. What is printed by the above C++ code? "IDL:A:1.0" or "IDL:B:1.0"? 2. If the typecode is for valuetype A, what happens to the members defined in valuetype B? Seems they must be inaccessable yet still recoverable if I convert the DynValue back to an any and extract the value, because I can't truncate a B to an A. 3. If the typecode is for valuetype B, we now have the interesting case where: tc->equivalent(ds->type()->member_type(0)) is false. Is this going to confuse programmers or programs? I think it will, since it means that if I try to insert dv into another DynStruct via assign() or the like, it will fail, since the TypeCodes are no longer equivalent. 4. Do the answers change if B is truncatable and the program can find the TypeCode for B (perhaps via SendingContextRunTime)? How about if it can't find the TypeCode? Resolution: Revised Text: Actions taken: July 16, 2002: received issue April 11, 2012: Deferred Discussion: End of Annotations:===== Sender: jon@floorboard.com Date: Tue, 16 Jul 2002 17:41:44 -0700 From: Jonathan Biggar X-Mailer: Mozilla 4.79 [en] (X11; U; SunOS 5.7 sun4u) X-Accept-Language: en To: issues@omg.org, corba-rtf@omg.org Subject: How does DynValue handle derived valuetypes? I just noticed that the description of DynValue is totally silent on the issue of derived valuetypes. Here's an example to set things up: // IDL valuetype A { public short s; }; valuetype B { public long l; }; struct S { A an_a; }; // C++ DynamicAny::DynFactory df = ...; B *b = ...; S my_s; CORBA::Any my_any; s.an_a = b; my_any <<= s; DynamicAny::DynAny_var da = df->create_dyn_any(my_any); DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(da); ds->seek(0); da = ds->current_component(); DynamicAny::DynValue_var dv = DynamicAny::DynValue::_narrow(da); CORBA::TypeCode_var tc = dv->type(); cout << tc->id() << endl; ----------- Now some questions: 1. What is printed by the above C++ code? "IDL:A:1.0" or "IDL:B:1.0"? 2. If the typecode is for valuetype A, what happens to the members defined in valuetype B? Seems they must be inaccessable yet still recoverable if I convert the DynValue back to an any and extract the value, because I can't truncate a B to an A. 3. If the typecode is for valuetype B, we now have the interesting case where: tc->equivalent(ds->type()->member_type(0)) is false. Is this going to confuse programmers or programs? I think it will, since it means that if I try to insert dv into another DynStruct via assign() or the like, it will fail, since the TypeCodes are no longer equivalent. 4. Do the answers change if B is truncatable and the program can find the TypeCode for B (perhaps via SendingContextRunTime)? How about if it can't find the TypeCode? Opinions and information about existing implementations would be appreciated. :) -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Reply-To: "Michi Henning" From: "Michi Henning" To: "Jonathan Biggar" , , Subject: Re: How does DynValue handle derived valuetypes? Date: Fri, 19 Jul 2002 09:04:52 +1000 Organization: Triodia Technologies X-Mailer: Microsoft Outlook Express 6.00.2600.0000 > I just noticed that the description of DynValue is totally silent on the > issue of derived valuetypes. > > Here's an example to set things up: > > // IDL > > valuetype A { > public short s; > }; > > valuetype B { > public long l; > }; > > struct S { > A an_a; > }; There is no derivation here... I assume that you mean valuetype B : A { /* ... */ }; > // C++ > > DynamicAny::DynFactory df = ...; > B *b = ...; > S my_s; > CORBA::Any my_any; > > s.an_a = b; > my_any <<= s; > > DynamicAny::DynAny_var da = df->create_dyn_any(my_any); > DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(da); This really boils down to the question of how the type code information is obtained at run time for a derived via a base reference. I'd argue that the derived type's ID must be used, otherwise polymorphism gets shot as soon as I use an Any. > > ds->seek(0); > da = ds->current_component(); > > DynamicAny::DynValue_var dv = DynamicAny::DynValue::_narrow(da); > CORBA::TypeCode_var tc = dv->type(); > > cout << tc->id() << endl; > > ----------- > > Now some questions: > > 1. What is printed by the above C++ code? "IDL:A:1.0" or > "IDL:B:1.0"? I haven't tried, but would argue that it should be "IDL:B:1.0". > 2. If the typecode is for valuetype A, what happens to the members > defined in valuetype B? Seems they must be inaccessable yet still > recoverable if I convert the DynValue back to an any and extract the > value, because I can't truncate a B to an A. Right. But I don't think the typecode should be for A. > 3. If the typecode is for valuetype B, we now have the interesting case > where: > > tc->equivalent(ds->type()->member_type(0)) > > is false. Is this going to confuse programmers or programs? I think it > will, since it means that if I try to insert dv into another DynStruct > via assign() or the like, it will fail, since the TypeCodes are no > longer equivalent. Bloody hell! I think the real issue here is that TypeCode::equivalent() is the wrong notion of equivalence to use. Instead, to cope with derivation correctly, I think we need something along the lines of TypeCode::assignment_compatible(). > 4. Do the answers change if B is truncatable and the program can find > the TypeCode for B (perhaps via SendingContextRunTime)? How about if it > can't find the TypeCode? Nasty :-( I distincly remember Steve++ saying years ago that "value types break dynamic anything" -- quite a prophetic remark... I have no good answer to the last scenario. Whether B is truncatable or not shouldn't matter, I think -- either way, the derived type information and value should be preserved. But it gets nasty if the type information can't be found. If I don't have B's type information available, I can't find out whether or not B is truncatable. It seems the only option then would be to fail. Cheers, Michi. -- Michi Henning Ph: +61 4 1118-2700 Triodia Technologies http://www.triodia.com/staff/michi Sender: jbiggar@Resonate.com Date: Thu, 18 Jul 2002 16:33:31 -0700 From: Jonathan Biggar X-Mailer: Mozilla 4.79 [en] (X11; U; SunOS 5.6 sun4u) X-Accept-Language: en To: Michi Henning CC: issues@omg.org, corba-rtf@omg.org Subject: Re: How does DynValue handle derived valuetypes? Michi Henning wrote: > > > I just noticed that the description of DynValue is totally silent on the > > issue of derived valuetypes. > > > > Here's an example to set things up: > > > > // IDL > > > > valuetype A { > > public short s; > > }; > > > > valuetype B { > > public long l; > > }; > > > > struct S { > > A an_a; > > }; > > There is no derivation here... I assume that you mean > > valuetype B : A { /* ... */ }; Yes, I meant to derive B from A. > > // C++ > > > > DynamicAny::DynFactory df = ...; > > B *b = ...; > > S my_s; > > CORBA::Any my_any; > > > > s.an_a = b; > > my_any <<= s; > > > > DynamicAny::DynAny_var da = df->create_dyn_any(my_any); > > DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(da); > > This really boils down to the question of how the type code > >information > is obtained at run time for a derived via a base reference. I'd > >argue that > the derived type's ID must be used, otherwise polymorphism gets shot > as soon as I use an Any. I'm not sure what you mean here. There has to be no problem with creating an Any using the TypeCode for A but a value for B, since otherwise the DII and DSI break. > > ds->seek(0); > > da = ds->current_component(); > > > > DynamicAny::DynValue_var dv = DynamicAny::DynValue::_narrow(da); > > CORBA::TypeCode_var tc = dv->type(); > > > > cout << tc->id() << endl; > > > > ----------- > > > > Now some questions: > > > > 1. What is printed by the above C++ code? "IDL:A:1.0" or > > "IDL:B:1.0"? > > I haven't tried, but would argue that it should be "IDL:B:1.0". > > > 2. If the typecode is for valuetype A, what happens to the > > members > > defined in valuetype B? Seems they must be inaccessable yet still > > recoverable if I convert the DynValue back to an any and extract > > the > > value, because I can't truncate a B to an A. > > Right. But I don't think the typecode should be for A. > > > 3. If the typecode is for valuetype B, we now have the > > interesting case > > where: > > > > tc->equivalent(ds->type()->member_type(0)) > > > > is false. Is this going to confuse programmers or programs? I > > think it > > will, since it means that if I try to insert dv into another > > DynStruct > > via assign() or the like, it will fail, since the TypeCodes are no > > longer equivalent. > > Bloody hell! I think the real issue here is that > > TypeCode::equivalent() is > the wrong notion of equivalence to use. Instead, to cope with > > derivation > correctly, I think we need something along the lines of > TypeCode::assignment_compatible(). That's why I'm leaning towards the correct answer to the question being that the TypeCode returned is A, not B, with B's extra members inaccessable inside the DynAny. Then we don't have to invent an assignment compatible test. The program (or programmer) isn't going to know it is a B anyway unless he explicitly tries to downcast it to a B. When it's wrapped in a DynValue, the downcast is a bit harder to do, since you have to extract it via get_val() or to_any() first. > > 4. Do the answers change if B is truncatable and the program can find > > the TypeCode for B (perhaps via SendingContextRunTime)? How about if it > > can't find the TypeCode? > > Nasty :-( I distincly remember Steve++ saying years ago that "value types > break dynamic anything" -- quite a prophetic remark... > > I have no good answer to the last scenario. Whether B is truncatable or not > shouldn't matter, I think -- either way, the derived type information and > value should be preserved. But it gets nasty if the type information can't > be found. If I don't have B's type information available, I can't find out > whether or not B is truncatable. It seems the only option then would > be to fail. I agree that if it can't find the TypeCode then it should fail, just as it would when unmarshalling from CDR. If it can find the TypeCode, then I really don't want the DynValue implementation to truncate, since we'd like Any and DynAny to be usable in things like the Event service to avoid truncation. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org