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...)


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
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.

  -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.

  -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.
      

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