From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Carlini To: bkoz@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org Subject: Re: libstdc++/1704 Date: Mon, 28 May 2001 06:16:00 -0000 Message-id: <20010528131604.4296.qmail@sourceware.cygnus.com> X-SW-Source: 2001-05/msg00957.html List-Id: The following reply was made to PR libstdc++/1704; it has been noted by GNATS. From: Paolo Carlini 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 > inline _CharT > toupper(_CharT __c, const locale& __loc) > { return use_facet >(__loc).toupper(__c); } > > with _CharT == int. This is allowed, but keep in mind that the standard locale doesn't have ctype as a standard facet, so thus use_facet has to fail: > > template > 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(*__fp); > } > > > So, std::bad_cast gets thrown here. This is, I believe, standard conformant behavior. To use ctype, you'd have to imbue it in the standard locale (and then add some kind of ctype 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(c), getloc()); > c = std::toupper(c, getloc()); > } > catch (std::exception& obj) > { > puts("trying to use ctype 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 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--