[std-interval] Re: winter 2006 draft for standard C++ intervals

Lawrence.Crowl at sun.com Lawrence.Crowl at sun.com
Sat Mar 4 00:01:16 PST 2006


Overall, I thought the proposal well written.  I do have some
comments.

(A date would have helped in identifying the document, even if you do
not yet have a document number.)

============

Should std::valarray<interval> be allowed?

   Note that Sun's interval library includes specializations for
   valarray over intervals.  This specialization improves performance
   over the simple approach.

Should intervals be passed by value or by reference?

   I strongly prefer the pass-by-value approach over the legacy
   pass-by-reference approach of std::complex.  The choice has
   implications beyond the efficiency of the interval operations
   because users will tend to copy the style of the standard.  This
   pass-by-reference style leads to inefficiency and incorrectness.

   "Changing [interval parameters from pass-by-reference] to pass by
   value would only penalize the other ABIs."

   What evidence do you have to support this claim?  In fact, for most
   ABIs, the performance of intervals pass-by-value will be faster
   than pass-by-reference.  On those ABIs where performance by-value
   is lower, it will be only marginally lower. (For example, on x86
   pass-by-value pushes two words to the stack; pass-by-reference
   varies from pushing one word to writing two words and pushing one.)
   On the other hand, ABIs that support "small structs passed in
   registers", the difference is signficant, often avoiding memory
   entirely.

   "Note that this point is moot when functions are inline, which is
   expected to be the case most of the time."

   This statement is entirely untrue for the simple implementations.

   Pass-by-reference inhibits optimization.  The problem is that
   pass-by-reference introduces potential aliases between parameters.
   The compiler must load/store intervals to memory at many
   intermediate stages of computation to avoid incorrect results.  In
   contrast, value parameters cannot be aliased, and hence may be
   retained in registers.

   The aliasing problem is particularly severe because programmers
   often write programs as though it did not exist.  That is, they
   write functions that fail when parameters are in fact aliased.
   For example, the typical code for complex::operator*= is:

      real = real*rhs.real - imag*rhs.imag;
      imag = imag*rhs.real + real*rhs.imag;

   and it fails under pass-by-reference for the expression c*=c.
   Workarounds to this problem genrally involve retaining an extra copy
   of something, which ends up being very similar to pass-by-value.

   Now, imagine all that code where the programmer did not account for
   aliasing in user-written functions.  Now imagine all that code just
   naturally corrected with pass-by-value.

   This issue is very important.

26.6 Interval Numbers

   Paragraph 2 has a stale reference to interval<bool>.

   Paragraph 2 also says "instantiating the template interval for any
   type other than ... is unspecified".  By omitting the generic
   template definition, and defining only the specializations, the user
   cannot instantiate interval over any other type and the unspecified
   behavior is gone.  Is there any particular reason to provide the
   generic template definition?  If not, I suggest you remove it.
   Section 26.6.2 would go away.

26.6.1 Header <interval> synopsis // values:

   Several of the free functions seem more natural to me as member
   functions.  They are inf, sup, midpoint, and width.

26.6.1 Header <interval> synopsis // algebraic operators:

   Why is square a "value", but sqrt is a "algebraic operator"?

26.6.1 Header <interval> synopsis // set operations:

   These operations seem much more natural to me as member functions.
   Consider:

      if ( contains( a, b ) )

   versus

      if ( a.contains(b) )

   or more signficiantly

      a = intersect( hull( a, b ), c );

   versus

      a = a.hull(b).intersect(c);

   As with the values functions, we need to balance the expectations of
   the users.  I speak of my expectations as a C++ expert, not of the
   expectations of an interval expert.  It may well be that changing
   would be worse than not.

26.6.11 interval static value operations

   Based on the example in VI.1, you also need

      interval<T> interval<T>::epsilon()
         { return interval( -std::numeric_limits<T>::min(), 
                             std::numeric_limits<T>::min() ); }

   And based on the example in VI.2, you also need

      interval<T> interval<T>::min()
         { return interval( std::numeric_limits<T>::min(), 
                            std::numeric_limits<T>::min() ); }

   which results in

      assign_box( r, -std::interval<T>::min() );

============

  Lawrence Crowl             650-786-6146   Sun Microsystems, Inc.
                   Lawrence.Crowl at Sun.com   16 Network Circle, UMPK16-303
           http://www.Crowl.org/Lawrence/   Menlo Park, California, 94025



More information about the Std-interval mailing list