stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: [jira] Commented: (STDCXX-742) [IBM XLC++ 9.0/AIX 5.3] 22.locale.messages fails with assertions
Date Wed, 02 Apr 2008 17:55:32 GMT
Travis Vitek wrote:
>  
> 
>> Martin Sebor wrote:
>>
>> Travis Vitek wrote:
>>>  
>>>
>>>> Travis Vitek commented on STDCXX-742:
>>>> -------------------------------------
>>>>
>>>> This is happening because we don't use the -qrtti=dynamiccast 
>>>> option. We internally use a dynamic_cast to determine if the 
>>>> facet is of the correct derived type, but if dynamic_cast 
>>>> isn't supported we use a C style cast, and that returns bad results.
>>>>
>>>> This case is essentially the same as STDCXX-664. We didn't add 
>>>> -qrtti=dynamiccast back then, and we just worked around the 
>>>> issue in the test. It seems to me that we should have added 
>>>> the flag. Would this be a binary compatible change?
>>>>
>>> What are the thoughts on this? There was some discussion
>>> [http://tinyurl.com/3xfdma] of enabling -qrtti=dynamiccast for the
>>> VisualAge C++ compiler, but it petered out. 
>> Is there any way to turn on rtti using a pragma? That way we could
>> enable it only for translation units that included <locale> and we
>> wouldn't be shoving the option down the throats of users who don't
>> care about named locales.
> 
> No, there is no pragma for this. Even if there were we would need to do
> some hacking to get it to work. We try determine if dynamic_cast<>()
> exists and is functioning correctly at configuration time. If that
> config test fails, we define _RWSTD_NO_DYNAMIC_CAST. So even if we
> managed to enable rtti when <locale> was included, we would need to
> 'fix' the _RWSTD_NO_DYNAMIC_CAST and _RWSTD_DYNAMIC_CAST macros. Ewww..

Or just add a special implementation just for XLC++. But sounds
like that's not possible anyway.

> 
>> Btw., does XLC++ itself correctly handle the test case mentioned
>> in the thread, even without -qrtti? (It's possible to get some
>> simple cases to work even w/o the option but not all of them).
>>
> 
> I'm not absolutely sure what you're asking. It sounds like you are
> asking if the Standard C++ Library implementation that ships with XLC++
> has this same problem.

That's exactly what I was asking, thanks.

> The answer to that is no...

I wonder if it would get this right:

     struct MyMessages: std::messages<char> { };
     assert (!std::has_facet<MyMessages>(std::locale::classic ()));

If not, they probably have their own simple version of "RTTI" built
into the facet (e.g., via a virtual function) but they still can't
handle tricky cases like this one. Unfortunately, we can't even do
this much w/o breaking binary compatibility.

All in all, I'm still not sure this fairly obscure corner case is
worth the effort of adding a compiler option for. C++ locales are
used by only a small community of users, and I suspect that this
case (calling has_facet or use_facet with a facet derived from one
of the standard ones) is unlikely to come up even in their "advanced"
uses. I say we open an issue for this just for the record and keep
deferring it until we feel like adding the option or until IBM
decides to enable RTTI by default.

Martin

> 
>     $ type t.cpp
>     #include <locale>
>     #include <cstring>
>     #include <cassert>
> 
>     template <class charT>
>     void test_has_facet (const char *loc_name, const char *cname)
>     {
>         const std::locale loc =
>             loc_name ? std::locale (loc_name) : std::locale ();
> 
>         typedef std::messages_byname<charT> ByName;
> 
>         const bool byname = loc_name
>             && std::strcmp (loc_name, "C");
> 
>         const bool facet_exists = std::has_facet<ByName>(loc);
> 
>         assert (byname == facet_exists);
> 
>         try {
>             // verify that use facet throws an exception only
>             // for the default and "C" locales
>             std::use_facet<ByName>(loc);
> 
>             assert (byname);
>         }
>         catch (std::exception &ex) {
>             assert (!byname);
>         }
>     }
> 
>     template <class charT>
>     void test_messages (charT, const char *cname)
>     {
>         // exercise has_facet and use_facet in the default locale
>         test_has_facet<charT>(0, cname);
> 
>         // exercise has_facet and use_facet in locale("C")
>         test_has_facet<charT>("C", cname);
>     }
> 
>     int main (int, char*[])
>     {
>         test_messages (char (), "char");
> 
>         return 0;
>     }
> 
>   $ xlC t.cpp -o t && ./t
>   $
> 
> If I run the same code under stdcxx, I get the following
> 
>   $ gmake t && ./t
> 
>   <snip>
> 
>   Assertion failed: byname == facet_exists, file t.cpp, line 18
>   IOT/Abort trap (core dumped)
>   $
> 
> Travis
> 


Mime
View raw message