Boost logo

Boost :

Subject: Re: [boost] [fusion] change on trunk breaking proto
From: Christopher Schmidt (mr.chr.schmidt_at_[hidden])
Date: 2009-12-10 15:15:20


Eric Niebler schrieb:
>
> Hi Fusion gurus. I'm chasing an elusive bug that the following Proto
> test has exposed:
>
> http://beta.boost.org/development/tests/trunk/developer/output/RW_WinXP_VC-boost-bin-v2-libs-proto-test-examples-test-msvc-9-0-debug-link-static-threading-multi.html
>
>
> All is well on the release branch, but on trunk, Proto's examples.cpp
> test is failing -- but only on MSVC! I suspect Fusion because if I
> replace the version of Fusion on trunk with the one on release all is
> well. (Caveat: when I do this, I also need to make a corresponding
> change to the as_callable function object in proto/transform/fold.hpp to
> accommodate the changed argument order of fusion::fold's functor.) It
> seems something is causing MSVC to prematurely instantiate a template
> used in a Proto transform, but I can't see what.
>
> I first suspected the recent changes to fusion::fold, but that seems not
> to be the case. If I just take the release version of fusion::fold, the
> problem still manifests. The problem must be elsewhere.
>
> Does anyone from Fusion team want to give this a crack? I'll be happy to
> help.
>

Changeset 57337, in particular the change in
boost/fusion/view/reverse_view/reverse_view.hpp, causes the trouble.
I only tested this changeset with my default toolchain (gcc 4.4) as I
did not consider any of my changes to be breaking. I am awfully sorry.

The change in reverse_view.hpp causes fusion::reverse_view to always be
a bidirectional access sequence, even if the underlying sequence is a
random access one. This is correct behaviour according to the documentation.

The problem in proto is probably caused by a bug in the VC9/VC10
compiler. The non-random-access implementation of fusion::detail::fold
wrongly causes the compiler to instantiate nested template parameters of
the functor.

I attached a minimal sample which reproduces this problem.
Interestingly, the random-access fold implementation works fine in your
particular usecase, whereas my sample reproduces the problem for forward
and random access sequences.
I also attached a temporary workaround-patch for proto. Unfortunately I
have no idea of how to "fix" fusion in the first place.
BTW, compiling the examples.cpp testcase with the upcoming C++0x port of
fusion and VC9 works fine.

-Christopher

Index: boost/proto/transform/fold.hpp
===================================================================
--- boost/proto/transform/fold.hpp (revision 58271)
+++ boost/proto/transform/fold.hpp (working copy)
@@ -198,10 +198,11 @@
                 {
                     typename when<_, Sequence>::template impl<Expr, State, Data> seq;
                     detail::as_callable<Fun, Data> f(d);
- return fusion::fold(
+ return fusion::detail::fold(
                         seq(e, s, d)
                       , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d)
                       , f
+ , fusion::random_access_traversal_tag()
                     );
                 }
             };



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk