Issue 1386: Any and WChar issue (cxx_revision) Source: (, ) Nature: Uncategorized Issue Severity: Summary: Summary: The C++ mapping requires that attempt to insert a Boolean, Octet, or Char value into an any must generate a compile-time error: CORBA::Any a; CORBA::Char c = "x"; a <<= c; // Compile-time error The spec says nothing about WChar and WChar *. This implies that no such guarantee exists. However, I don"t think it would hurt to spell this out: CORBA::Any a; CORBA::WChar wc = L"x"; a <<= wc; // Undefined behavior Resolution: closed, fixed Revised Text: nsert the following text on page 20-59 of ptc/98-09-03, prior to the paragraph beginning with "Because valuetypes": Note that the following code has undefined behavior in non-standard C++ environments: CORBA::Any a; CORBA::WChar wc = L'x'; a <<= wc; // Undefined behavior This code may erroneously insert an integer type in environments where wchar_t is not a distinct type. On page 20-62, preceding the para beginning with "For non-primitive types...", insert the following text: Note that the following code has undefined behavior in non-standard C++ environments: CORBA::Any a = ...; CORBA::WChar wc; a >>= wc; // Undefined behavior This code may erroneously extract an integer type in environments where wchar_t is not a distinct type. Add the following text as the final paragraph of 20.16.4: In standard C++ environments, the mapping must declare the from_* and to_* constructors as explicit. This prevents undesirable conversions via temporaries. Actions taken: May 19, 1998: received issue March 19, 1999: closed issue Discussion: End of Annotations:===== Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Tue, 19 May 1998 14:34:15 +1000 (EST) From: Michi Henning To: cxx_revision@omg.org, issues@omg.org Subject: More on Any and WChar The C++ mapping requires that attempt to insert a Boolean, Octet, or Char value into an any must generate a compile-time error: CORBA::Any a; CORBA::Char c = 'x'; a <<= c; // Compile-time error The spec says nothing about WChar and WChar *. This implies that no such guarantee exists. However, I don't think it would hurt to spell this out: CORBA::Any a; CORBA::WChar wc = L'x'; a <<= wc; // Undefined behavior Depending on the implementation, this may set the type code to indicate a wide character, or it may set it to indicate an integer type. Maybe the above example could be added to the spec? A similar issue exists for arrays. If WChar maps to an integer type, we can get problems: // IDL typedef long my_array[10]; // C++ CORBA::WChar * s = L"Hello"; CORBA::Any a; a <<= s; // Type code will be array!!! This will happen if IDL long and wchar both map to the same underlying C++ integer type (quite likely for non-ANSI compilers). The insertion compiles because the default conversion rules work out that they can construct a temporary my_array_forany class to find a parameter match for void operator<<=(Any &, const my_array_forany &). Unfortunately, I can't figure out a way to prevent this - no problem for ANSI C++, but for non-ANSI environments, I can't see a sensible fix (short of mapping wstring to a class, which would guarantee distinguishability) Anyone have any ideas? Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Return-Path: Sender: jon@floorboard.com Date: Mon, 18 May 1998 22:47:17 -0700 From: Jonathan Biggar To: Michi Henning CC: cxx_revision@omg.org, issues@omg.org Subject: Re: More on Any and WChar References: Michi Henning wrote: > > The C++ mapping requires that attempt to insert a Boolean, Octet, or > Char value into an any must generate a compile-time error: > > CORBA::Any a; > CORBA::Char c = 'x'; > a <<= c; // Compile-time error > > The spec says nothing about WChar and WChar *. This implies that no > such > guarantee exists. However, I don't think it would hurt to spell this > out: > > CORBA::Any a; > CORBA::WChar wc = L'x'; > a <<= wc; // Undefined behavior > > Depending on the implementation, this may set the type code to > indicate > a wide character, or it may set it to indicate an integer type. > Maybe the above example could be added to the spec? Right. > A similar issue exists for arrays. If WChar maps to an integer type, we > can get problems: > > // IDL > typedef long my_array[10]; > > // C++ > CORBA::WChar * s = L"Hello"; > CORBA::Any a; > a <<= s; // Type code will be array!!! > > This will happen if IDL long and wchar both map to the same underlying > C++ integer type (quite likely for non-ANSI compilers). The insertion > compiles because the default conversion rules work out that they can > construct a temporary my_array_forany class to find a parameter match for > void operator<<=(Any &, const my_array_forany &). But why should it prefer that to the: void CORBA::Any::operator <<=(const CORBA::WChar *); operator? It seems that that should be preferred, because it is an exact match. > Unfortunately, I can't figure out a way to prevent this - no problem > for ANSI C++, but for non-ANSI environments, I can't see a sensible > fix > (short of mapping wstring to a class, which would guarantee > distinguishability) Since the programmer can explicitly use from_wstring or the _forany, it's not a showstopper. The spec should also state that the _forany constructors be defined as explicit in an ANSI C++ mapping to prevent accidental use without the _forany. Explicit should also be added to the mappings for the Any::from_* and Any::to_* classes. This still doesn't help non-ANSI environments. The best the spec can do is to state that not using the from_* or _forany classes can lead to non-portable code. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org Return-Path: X-Authentication-Warning: tigger.dstc.edu.au: michi owned process doing -bs Date: Tue, 19 May 1998 15:57:17 +1000 (EST) From: Michi Henning To: Jonathan Biggar cc: cxx_revision@omg.org, issues@omg.org Subject: Re: More on Any and WChar On Mon, 18 May 1998, Jonathan Biggar wrote: > > A similar issue exists for arrays. If WChar maps to an integer type, we > > can get problems: > > > > // IDL > > typedef long my_array[10]; > > > > // C++ > > CORBA::WChar * s = L"Hello"; > > CORBA::Any a; > > a <<= s; // Type code will be array!!! > > > > This will happen if IDL long and wchar both map to the same underlying > > C++ integer type (quite likely for non-ANSI compilers). The insertion > > compiles because the default conversion rules work out that they can > > construct a temporary my_array_forany class to find a parameter match for > > void operator<<=(Any &, const my_array_forany &). > > But why should it prefer that to the: > > void CORBA::Any::operator <<=(const CORBA::WChar *); > > operator? It seems that that should be preferred, because it is an > exact match. If wchar_t and WChar both map to C++ long in a non-ANSI environment, they are indistinguishable, so there is no longer an exact match. > Since the programmer can explicitly use from_wstring or the _forany, > it's not a showstopper. Yes. I was trying to point out that when I make this mistake for boolean, I am guaranteed a compile-time error, but if I make the same mistake for a wide string, I get undefined behavior. Unfortunately, all ways I can think of that would force a compile-time error would require rather drastic changes to the mapping. > The spec should also state that the _forany > constructors be defined as explicit in an ANSI C++ mapping to > prevent > accidental use without the _forany. Explicit should also be added > to > the mappings for the Any::from_* and Any::to_* classes. I think that's an excellent idea for ANSI environments! > This still doesn't help non-ANSI environments. The best the spec can do > is to state that not using the from_* or _forany classes can lead to > non-portable code. I think we should add a warning along those lines, simply because this error can go undetected for a long time (in fact, depending on the implementation, I may have the code work perfectly well only to fall over when it is ported). Cheers, Michi. -- Michi Henning +61 7 33654310 DSTC Pty Ltd +61 7 33654311 (fax) University of Qld 4072 michi@dstc.edu.au AUSTRALIA http://www.dstc.edu.au/BDU/staff/michi-henning.html Date: Sun, 21 Feb 1999 10:25:52 +1000 (EST) From: Michi Henning To: C++ Revision Task Force Subject: Proposal for 1386 Organization: Triodia Technologies Insert the following text on page 20-59, following the bullet list: Note that the following code has undefined behavior in non-standard C++ environments: CORBA::Any a; CORBA::WChar wc = L'x'; a <<= wc; // Undefined behavior This code may erroneously insert an integer type in environments where wchar_t is not a distinct type. On page 20-62, preceding the para beginning with "For non-primitive types...", inser the following text: Note that the following code has undefined behavior in non-standard C++ environments: CORBA::Any a = ...; CORBA::WChar wc; a >>= wc; // Undefined behavior This code may erroneously extract an integer type in environments where wchar_t is not a distinct type. Add the following text as the final para of 20.16.14: In standard C++ environments, the mapping must declare the from_* and to_* constructors as explicit. This prevents undesirable conversions via temporaries. 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