This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Rethinking... (Re: RFC: fp printing speedup...)


Martin Sebor writes:
 > Jerry Quinn wrote:
 > > Paolo Carlini writes:
 > >  > Thanks Martin,
 > >  > 
 > >  > everything is clear to me, now, I really needed some additional
 > >  > clarifications after Nathan harsh (but correct, I know, I know...)
 > >  > way of putting the issue...
 > >  > 
 > >  > Please let me know (privately, perhaps) if I can help somehow for
 > >  > the DR...
 > >  > 
 > >  > *Many* thanks again to everyone!
 > >  > 
 > >  > Paolo.
 > > 
 > > Wow!  I'm surprised at the fallout from this issue :-)  I checked my
 > > email tonight and found quite a thread.
 > > 
 > > Let me know if I can help with the DR as well.
 > 
 > This is what I've got so far. Let me know if it sums it up or if
 > either of you (or anyone else) thinks I missed something (or got
 > something wrong).
 > 
 > Thanks
 > Martin
 > Most ctype member functions come in two flavors: one that operates
 > on a single character at a time and another that operates on a range
 > of characters. Both flavors are typically described by a single
 > Effects and/or Returns clause.
 > 
 > The Returns clause of each of the single-character non-virtual forms
 > suggests that the function calls the corresponding single character
 > virtual function, and that the array form calls the corresponding
 > virtual array form. Neither of the two forms of each virtual member
 > function is required to be implemented in terms of the other.
 > 
 > There are three problems:
 > 
 > 1. One is that while the standard does suggest that each non-virtual
 > member function calls the corresponding form of the virtual function,
 > it doesn't actually explicitly require it.
 > 
 > Implementations that cache results from some of the virtual member
 > functions for some or all values of their arguments might want to
 > call the array form from the non-array form the first time to fill
 > the cache and avoid any or most subsequent virtual calls. Programs
 > that rely on each form of the virtual function being called from
 > the corresponding non-virtual function will see unexpected behavior
 > when using such implementations.
 > 
 > 2. The second problem is that either form of each of the virtual
 > functions can be overridden by a user-defined function in a derived
 > class to return a value that is different from the one produced by
 > the virtual function of the alternate form that has not been
 > overriden.
 > 
 > Thus, it might be possible for, say, ctype::widen(c) to return one
 > value, while for ctype::widen(&c, &c + 1, &wc) to set wc to another
 > value. This is almost certainly not intended. Both forms of every
 > function should be required to return the same result for the same
 > character, otherwise the same program using an implementation that
 > calls one form of the functions will behave differently than when
 > using another implementation that calls the other form of the
 > function "under the hood."
 > 
 > 2. The last problem is that the standard text fails to specify

3, not 2.

 > whether one form of any of the virtual functions is permitted
 > to be implemented in terms of the other form or not, and if so,
 > whether it is required or permitted to call the overridden
 > virtual function or not.
 > 
 > Thus, a program that overrides one of the virtual functions so that
 > it calls the other form which then calls the base member might end
 > up in an infinite loop if the called form of the base implementation
 > of the function in turn calls the other form.
 > 
 > To fix these problems I propose the following:
 > 
 > Add two paragraphs immediately after 22.2.1.1 [lib.locale.ctype],
 > p2, with the following text:
 > 
 >   -3- Each ctype non-virtual member function that comes in two forms,
 >       one that takes a range of elements of char_type, and another
 >       that takes just a single element of char_type, is required to
 >       call the corresponding form of the virtual member function
 >       with the same value of char_type to obtain the result. The
 >       result for the same argument may be cached and returned from
 >       subsequent calls to either form of the non-virtual member
 >       function with that argument.

Might it not be better to allow both non-virtual forms to be
implemented in terms of whichever virtual function is more convenient
to use?  That would simplify caching, since the single form could call
the array virtual to initialize the cache and get its result.

 >   -4- Each ctype virtual member function that comes in two forms
 >       (as explained above) is required to produce the same result
 >       for the same value of char_type from each form.

widen takes char, not char_type.  Perhaps:

 -4- For each ctype virtual member function that comes in two forms,
     the single-element form must produce the same result for an
     element c that the array form produces for the single-element
     array containing c.

 
 >   -5- It is unspecified whether the array form of each virtual
 >       member function calls the single-element virtual overload
 >       of the same function in a loop, or whether the single
 >       element form calls the array form with an array of a single
 >       element with the value of its argument, or whether neither
 >       form calls the other. In any case, an implementation is not
 >       permitted to call the other form of any virtual member
 >       function overridden in a derived class.

There's no way to tell that the virtual member is overridden, is
there?  This clause seems to say that neither form may call the other,
period.  I think that's what you have to do to solve the infinite
loop, right?  If so, how about:

 -5- Neither the array nor single-element form of virtual member
     function may call the other form.

This potentially leads to some code duplication, but doesn't require
figuring out whether the member is being overridden.

Jerry

ps: While we're at it, 22.2.1.3.2 p10 and p11, should probably read:

Returns: do_widen(c) or do_widen(low, high, to).

and

Returns: do_narrow(c, dfault) or do_narriw(low, high, dfault, to).


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