This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: libstdc++/1704


The following reply was made to PR libstdc++/1704; it has been noted by GNATS.

From: Paolo Carlini <pcarlini@unitus.it>
To: bkoz@gcc.gnu.org
Cc: nicolai.josuttis@braunschweig.netsurf.de, bkoz@redhat.com,
 	gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org
Subject: Re: libstdc++/1704
Date: Mon, 28 May 2001 15:11:36 +0200

 --------------EEE41B84D882FF41F380C7A1
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 Hi,
 
 so, I understand from your detailed analysis that this is just a QoI issue?
 Honestly, as a beginner C++ programmer I slightly prefer the solution adopted by STLport: a conversion error is issued at compile time. Otherwise I find this kind of programming errors *very* difficult to debug ...
 
 Thanks,
 Paolo Carlini.
 
 
 bkoz@gcc.gnu.org wrote:
 
 > Synopsis: Null output from Josuttis example
 >
 > Responsible-Changed-From-To: unassigned->bkoz
 > Responsible-Changed-By: bkoz
 > Responsible-Changed-When: Fri May 25 11:33:14 2001
 > Responsible-Changed-Why:
 >     Mine.
 > State-Changed-From-To: analyzed->feedback
 > State-Changed-By: bkoz
 > State-Changed-When: Fri May 25 11:33:14 2001
 > State-Changed-Why:
 >     I don't thing this is a bug, really.
 >     In particular,
 >     c = std::toupper(c, getloc());
 >
 >     where c == int_type attempts to instantiate
 >
 >       template<typename _CharT>
 >         inline _CharT
 >         toupper(_CharT __c, const locale& __loc)
 >         { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
 >
 >     with _CharT == int. This is allowed, but keep in mind that the standard locale doesn't have ctype<int> as a standard facet, so thus use_facet has to fail:
 >
 >       template<typename _Facet>
 >         const _Facet&
 >         use_facet(const locale& __loc)
 >         {
 >           typedef locale::_Impl::__vec_facet        __vec_facet;
 >           size_t __i = _Facet::id._M_index;
 >           __vec_facet* __facet = __loc._M_impl->_M_facets;
 >           const locale::facet* __fp = (*__facet)[__i];
 >           if (__fp == 0 || __i >= __facet->size())
 >             __throw_bad_cast();
 >           return static_cast<const _Facet&>(*__fp);
 >         }
 >
 >
 >     So, std::bad_cast gets thrown here. This is, I believe, standard conformant behavior. To use ctype<int>, you'd have to imbue it in the standard locale (and then add some kind of ctype<int> functionality, which is of course a bit of a job.)
 >
 >     Instead, I suggest casting the argument to toupper to either char or wchart_t, so that the standard ctype facets are used. I suspect this is the intent of the code.
 >
 >     Nico?
 >
 >     -benjamin
 >
 >
 >     class outbuf : public std::streambuf
 >     {
 >     protected:
 >       virtual int_type overflow(int_type c)
 >       {
 >         if (c != EOF)
 >           {
 >         // convert lowercase to uppercase
 >         try
 >           {
 >             //      c = std::toupper(static_cast<char>(c), getloc());
 >             c = std::toupper(c, getloc());
 >           }
 >         catch (std::exception& obj)
 >           {
 >             puts("trying to use ctype<int> in a locale that doesn't have it");
 >           }
 >
 >         // and write the character to the standard output
 >         if (std::putchar(c) == EOF)
 >           return EOF;
 >           }
 >         return c;
 >       }
 >     };
 >
 > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=1704&database=gcc
 
 
 
 --------------EEE41B84D882FF41F380C7A1
 Content-Type: text/html; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 <html>
 Hi,
 <p>so, I understand from your detailed analysis that this is just a QoI
 issue?
 <br>Honestly, as a beginner C++ programmer I slightly prefer the solution
 adopted by STLport: a conversion error is issued at compile time. Otherwise
 I find this kind of programming errors *very* difficult to debug ...
 <p>Thanks,
 <br>Paolo Carlini.
 <br>&nbsp;
 <p>bkoz@gcc.gnu.org wrote:
 <blockquote TYPE=CITE>Synopsis: Null output from Josuttis example
 <p>Responsible-Changed-From-To: unassigned->bkoz
 <br>Responsible-Changed-By: bkoz
 <br>Responsible-Changed-When: Fri May 25 11:33:14 2001
 <br>Responsible-Changed-Why:
 <br>&nbsp;&nbsp;&nbsp; Mine.
 <br>State-Changed-From-To: analyzed->feedback
 <br>State-Changed-By: bkoz
 <br>State-Changed-When: Fri May 25 11:33:14 2001
 <br>State-Changed-Why:
 <br>&nbsp;&nbsp;&nbsp; I don't thing this is a bug, really.
 <br>&nbsp;&nbsp;&nbsp; In particular,
 <br>&nbsp;&nbsp;&nbsp; c = std::toupper(c, getloc());
 <p>&nbsp;&nbsp;&nbsp; where c == int_type attempts to instantiate
 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template&lt;typename _CharT>
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inline _CharT
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; toupper(_CharT __c, const
 locale&amp; __loc)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { return use_facet&lt;ctype&lt;_CharT>
 >(__loc).toupper(__c); }
 <p>&nbsp;&nbsp;&nbsp; with _CharT == int. This is allowed, but keep in
 mind that the standard locale doesn't have ctype&lt;int> as a standard
 facet, so thus use_facet has to fail:
 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template&lt;typename _Facet>
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const _Facet&amp;
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; use_facet(const locale&amp;
 __loc)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef locale::_Impl::__vec_facet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 __vec_facet;
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t __i =
 _Facet::id._M_index;
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __vec_facet*
 __facet = __loc._M_impl->_M_facets;
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const locale::facet*
 __fp = (*__facet)[__i];
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (__fp ==
 0 || __i >= __facet->size())
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 __throw_bad_cast();
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return static_cast&lt;const
 _Facet&amp;>(*__fp);
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 <br>&nbsp;
 <p>&nbsp;&nbsp;&nbsp; So, std::bad_cast gets thrown here. This is, I believe,
 standard conformant behavior. To use ctype&lt;int>, you'd have to imbue
 it in the standard locale (and then add some kind of ctype&lt;int> functionality,
 which is of course a bit of a job.)
 <p>&nbsp;&nbsp;&nbsp; Instead, I suggest casting the argument to toupper
 to either char or wchart_t, so that the standard ctype facets are used.
 I suspect this is the intent of the code.
 <p>&nbsp;&nbsp;&nbsp; Nico?
 <p>&nbsp;&nbsp;&nbsp; -benjamin
 <br>&nbsp;
 <p>&nbsp;&nbsp;&nbsp; class outbuf : public std::streambuf
 <br>&nbsp;&nbsp;&nbsp; {
 <br>&nbsp;&nbsp;&nbsp; protected:
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; virtual int_type overflow(int_type c)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c != EOF)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // convert lowercase to
 uppercase
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = std::toupper(static_cast&lt;char>(c),
 getloc());
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 c = std::toupper(c, getloc());
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (std::exception&amp;
 obj)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 puts("trying to use ctype&lt;int> in a locale that doesn't have it");
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and write the character
 to the standard output
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (std::putchar(c) == EOF)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EOF;
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return c;
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 <br>&nbsp;&nbsp;&nbsp; };
 <p><a href="http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=1704&database=gcc";>http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&amp;pr=1704&amp;database=gcc</a></blockquote>
 
 <br>&nbsp;</html>
 
 --------------EEE41B84D882FF41F380C7A1--
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]