Issue 2335: Extraction from Any by pointer (cxx_revision) Source: (, ) Nature: Uncategorized Issue Severity: Summary: Summary: the mapping currently specifies that for char * and WChar *, the following extraction operators must be defined on type Any: class Any { Boolean operator>>=(const Any &, char * &); Boolean operator>>=(const Any &, WChar * &); // ... }; For user-defined complex types and other variable-length types, the mapping requires: class Any { Boolean operator>>=(const Any &, T * &); // ... }; This means that a conforming ORB need not compile the following: CORBA::Any a = ...; const char * p; a >>= p; // No matching operator This is a Bad Thing (TM), in my opinion. The reason is that when I extract something by pointer, first, the Any retains ownership and, second, I must treat the pointed-to memory as read-only. Resolution: fixed, issue closed Revised Text: Change second extraction operator near the bottom of page 20-61 of ptc/98-09-03 (the one for extraction by pointer) to read: Boolean operator>>=(const Any&, T*&); // Deprecated Boolean operator>>=(const Any&, const T*&); Add a note or footnote to state that: The non-constant version of the operator will be deprecated in a future version of the mapping and should not be used. Change the para in the middle of page 20-62 that currently reads For non-primitive types, such as struct, union, sequence, exception, Any, and valuetype, extraction is done by pointer. For example, consider the following IDL struct: to the following: For non-primitive types, such as struct, union, sequence, exception, and Any, extraction is done by constant pointer (valuetypes are extracted by non-const pointer, however, because valuetype operations do not support const.) For example, consider the following IDL struct: Change the code examples that follows to read: // C++ Any a; // ... a is somehow given a value of type MyStruct ... const MyStruct * struct_ptr; if (a >>= struct_ptr) { // ... use the value ... } Overload the constructors for to_string and to_wstring on page 20-65 for const pointers (the public members need to be references to constant pointers) and mark the old constructors as deprecated: struct to_string { to_string(const char *&s, ULong b) : val(s), bound(b) {} const char *&val; ULong bound; // Deprecated: to_string(char *&s, ULong b) : val(s), bound(b) {} }; struct to_wstring { to_wstring(const WChar *&s, ULong b) : val(s), bound(b) {} const WChar *&val; ULong bound; // Deprecated: to_wstring(WChar *&s, ULong b) : val(s), bound(b) {} }; Add a note to state: The non-constant versions of the constructors will be removed in a future version of the mapping and should not be used. Change the code example for string extraction on page 20-66 to adjust it for extraction by constant pointer. const char * p = "bounded"; any <<= Any::from_string(p, 8); // ... if (any >>= Any::to_string(p, 8)) { // ...any contained a string<8>... } Actions taken: January 22, 1999: received issue March 19, 1999: closed issue Discussion: End of Annotations:===== Date: Fri, 22 Jan 1999 15:46:19 +1000 (EST) From: Michi Henning Reply-To: cxx_revision@omg.org To: cxx_revision@omg.org cc: issues@omg.org Subject: Extraction from Any by pointer Organization: Triodia Technologies Hi, the mapping currently specifies that for char * and WChar *, the following extraction operators must be defined on type Any: class Any { Boolean operator>>=(const Any &, char * &); Boolean operator>>=(const Any &, WChar * &); // ... }; For user-defined complex types and other variable-length types, the mapping requires: class Any { Boolean operator>>=(const Any &, T * &); // ... }; This means that a conforming ORB need not compile the following: CORBA::Any a = ...; const char * p; a >>= p; // No matching operator This is a Bad Thing (TM), in my opinion. The reason is that when I extract something by pointer, first, the Any retains ownership and, second, I must treat the pointed-to memory as read-only. However, the way things are mapped, I *cannot* do the safe thing and extract by pointer-to-const and I'm forced to do the unsafe thing. Not only does this mean that I may accidentally modify storage I don't own, I also have to watch out that I don't accidentally pass ownership: CORBA::Any a = ...; char * p; a >>= p; // Assume extraction works // A long time later at a different spot in the code...: CORBA::String_var s = p; // Big trouble!!! It appears that the current mapping is exactly the wrong way round. It should require the extraction operators to be overloaded for const T * &, and to be absent for T * &. Proposal: For this revision of the mapping, require overloading on both const T * & and T * &. This at least gets rid of the problem of not being able to extract into a const pointer. Add a remark that the non-const extractors are deprecated. In the next revision of the mapping, remove the non-const versions. Cheers, Michi. -- Michi Henning +61 7 3236 1633 Triodia Technologies +61 4 1118 2700 (mobile) PO Box 372 +61 7 3211 0047 (fax) Annerley 4103 michi@triodia.com AUSTRALIA http://www.triodia.com/staff/michi-henning.html Date: Mon, 15 Feb 1999 13:20:00 +1000 (EST) From: Michi Henning To: cxx_revision@omg.org Subject: Proposal for 2335 Organization: Triodia Technologies As outlined in http://www.omg.org/issues/issue2335.txt, extraction by pointer from an Any is dangerous because it forces extraction as a non-const pointer. This proposal deprecates extraction by non-constant pointer by overloading the relevant functions for both constant and non-constant pointers, marking the non-constant versions as deprecated. (We can remove the non-constant versions in a future revision.) Proposal: Change second extraction operator near the bottom of page 20-61 (the one for extraction by pointer) to read: Boolean operator>>=(const Any&, T*&); // Deprecated Boolean operator>>=(const Any&, const T*&); Add a note or footnote to state that: The non-constant version of the operator will be deprecated in a future version of the mapping and should not be used. Change the para in the middle of page 20-62 that currently reads For non-primitive types, such as struct, union, sequence, exception, Any, and valuetype, extraction is done by pointer. For example, consider the following IDL struct: to the following: For non-primitive types, such as struct, union, sequence, exception, Any, and valuetype, extraction is done by constant pointer. For example, consider the following IDL struct: Change the code examples that follows to read: // C++ Any a; // ... a is somehow given a value of type MyStruct ... const MyStruct * struct_ptr; if (a >>= struct_ptr) { // ... use the value ... } Overload the constructors for to_string and to_wstring on page 20-65 for const pointers (the public members need to be references to constant pointers) and mark the old constructors as deprecated: struct to_string { to_string(const char *&s, ULong b) : val(s), bound(b) {} const char *&val; ULong bound; // Deprecated: to_string(char *&s, ULong b) : val(s), bound(b) {} }; struct to_wstring { to_wstring(const WChar *&s, ULong b) : val(s), bound(b) {} const WChar *&val; ULong bound; // Deprecated: to_wstring(WChar *&s, ULong b) : val(s), bound(b) {} }; Add a note to state: The non-constant versions of the constructors will be removed in a future version of the mapping and should not be used. Change the code example for string extraction on page 20-66 to adjust it for extraction by constant pointer. (Even if this proposal is rejected, we still need to fix this code example because it assigns a string literal to a char *, which is illegal in ANSI C++.) const char * p = "bounded"; any <<= Any::from_string(p, 8); // ... if (any >>= Any::to_string(p, 8)) { // ...any contained a string<8>... } Cheers, Michi. -- Michi Henning +61 7 3236 1633 Triodia Technologies +61 4 1118 2700 (mobile) PO Box 372 +61 7 3211 0047 (fax) Annerley 4103 michi@triodia.com AUSTRALIA http://www.triodia.com/staff/michi-henning.html