std::partial_sum( first, last, result, binary_op ) (§26.4.2) is defined as

  binary_op(binary_op(..., binary_op(*first, *(first + 1)),...),
  *(first + (i - result)))

Ambiguity notwithstanding (what is the first value??), the result of each
application is clearly supposed to be forwarded to the next.

However, the current implementation does this:

      typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
…
          __value = __binary_op(__value, *__first);

This would be safer:

      typedef typename _BinaryOperation::result_type _ValueType;

Copying *first to *result would require an implicit cast from
iterator_traits<_InputIterator>::value_type to _BinaryOperation::result_type,
which is not required. Since an additional __binary_op() is not allowed,

      _ValueType __value( *__first );

might be the best compromise. Anyway, implicit casting the result_type to the
input iterator type, as the current implementation does, seems much riskier.

The motivating case is pretty simple: I was specifically trying to avoid
overflow by summing a std::vector<char> into a std::vector<int>. Furthermore,
std::accumulate does correctly avoid overflow.


-- 
           Summary: std::partial_sum performs improper casts
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: potswa at mac dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42943

Reply via email to