Topic: std::accumulate and std::transform requirements in the current


Author: Alberto Ganesh Barbati <AlbertoBarbati@libero.it>
Date: Thu, 21 Sep 2006 22:55:53 CST
Raw View
kanze ha scritto:
> Alberto Ganesh Barbati wrote:
>
>> However, with the new wording, any such optimization is
>> impossible. For example, in the cited thread, someone used
>> std::transform with a binary_op that kept the number of times
>> the operator has been invoked and used it to compute the
>> result.
>
> Where does it say that traversal will be in order for transform?
> If your code counts on in-order traversal, it has undefined
> behavior unless the standard guarantees in order traversal.  (In
> the case of an instantiation using an input iterator, this is
> perhaps an open question, since input iterators don't really
> allow any other kind of traversal.)

Ah! That's it. I was looking at it in the wrong way. As the standard
doesn't guarantee how traversal happen, if you rely on a specific
traversal then you're on your own. Now it's clear, thank you.

> There is another problem involving state, however: none of the
> algorithms concerned make any guarantees concerning when and how
> often the binary_op will be copied.  Presumably, an
> implementation which copies it new directly from the argument
> each time, and uses the copy, is also legal.  In which case,
> mutable state can only be used through indirection.  (I had
> wondered in the past whether this wasn't an oversight,
> particularly with regards to the functional object in for_each,
> but the note in    25/9 of the current draft makes it clear that
> this is intentional.)

I was aware of the problem of copies. Thanks for the clarification, anyway.

>> Such an operator would violate the requirements in the current
>> standard but not those in the draft. Such operator can work
>> correctly only if the transform operation is performed in the
>> correct order.
>
> If an operator violates the requirements of the standard, you
> have undefined behavior.  In order to give a correct result, it
> must not only not violate the requirements of the standard, it
> must not depend on guarantees not given in the standard.  In the
> case of transform, for example, it must not depend on an in
> order traversal.  Doing so does not cause undefined behavior,
> but it does mean that the result is not specified.

Ah, cool! So it's undefined behavior in the current standard but
unspecified behavior in the draft. Makes sense! It made me nervous to
think that having mutable state in binary_op could reformat my HD :-D

>> If parallelism/reordering is being ruled out, then why not
>> going further and specify that the operation must be performed
>> in the right order?  There is already a precedent for that,
>> namely std::for_each, so why not std::transform?
>
> Probably because it isn't considered important for transform.
> The "normal" use of the algorithm should not depend on an in
> order traversal, and IMHO it is preferable to allow potential
> optimizations of the normal use, rather than ban them because of
> some rare or exotic uses.

Sure, std::transform is correct as it is (in the draft) and now I
understand why.

Thanks,

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]