Opened 14 years ago
Closed 7 years ago
#2823 closed Bugs (fixed)
[fusion] vector copy constructor copies sequence members in different order on different platforms
Reported by: | Owned by: | Joel de Guzman | |
---|---|---|---|
Milestone: | Boost 1.39.0 | Component: | fusion |
Version: | Boost 1.38.0 | Severity: | Problem |
Keywords: | Cc: |
Description
The generalized fusion::vector copy constructor for constructing from arbitrary fusion sequences does its copying in reverse order on one of my machines. This does not occur with vector copy assignment, and does not occur at all with fusion::list (see attached code).
In all my real world use this has not made a difference; I uncovered it in a unit test. The attached code shows what happens when you use transform_view to transform a fusion sequence with a stateful fusion functor.
Correct order: Mac PPC OS 10.5.6 Darwin Kernel 9.6.0 gcc 4.2.1
Reverse order: Linux 2.6.9-42.0.3.ELsmp i686 i686 i386 gcc 4.2.4
Attachments (3)
Change History (14)
by , 14 years ago
comment:1 by , 14 years ago
comment:2 by , 12 years ago
It looks like a compiler bug, should this be marked as wontfix
appropriately, and have a different issue for the documentation changes? Joel?
comment:3 by , 12 years ago
Dean, it's not a compiler bug. This is a known problem. The order of evaluation of function call arguments are undefined accd' to standard. Need further to look into this.
follow-up: 5 comment:4 by , 12 years ago
I've run into this problem recently, and bugged Hartmut about it on IRC. My solution to the implementation defined behavior that makes all fusion sequence operations have an unpredictable execution ordering. My solution was to create my own version of fusion::as_list that has a guaranteed execution order. The key being to make copies of the sequence values in the correct ordering. Which boils down to changing fusion::detail::build_cons<First,Last,false>::call(...) from:
static type call(First const& f, Last const& l) { return type(*f, next_build_cons::call(fusion::next(f), l)); }
To:
static type call(First const& f, Last const& l) { typename result_of::value_of<First>::type v = *f; return type(v, next_build_cons::call(fusion::next(f), l)); }
comment:5 by , 12 years ago
Replying to grafik:
The key being to make copies of the sequence values in the correct ordering. Which boils down to changing fusion::detail::build_cons<First,Last,false>::call(...) from:
...
To:
...
Interesting. Let me try that locally and run the tests -- unfortunately I cannot test on multiple platforms. I'll attach the patch for testing.
by , 12 years ago
Attachment: | boost-fusion-issue2823.diff added |
---|
Patch as proposed by Rene, applies to r66834.
comment:6 by , 12 years ago
comment:7 by , 12 years ago
Owner: | changed from | to
---|
comment:8 by , 12 years ago
Owner: | changed from | to
---|
On-list, Steven Watanabe wrote:
> result_of::deref would be better. There's no reason to make an extra copy. (Although this code looks pretty copy-happy to begin with).
Joel says that he will take it from here; assigning back to him. However, the patch that I applied does fix the bug.
comment:9 by , 12 years ago
I've updated the patch (made against the latest in Trunk, 67745) which implements the suggestion. Please see the new attachment.
by , 12 years ago
Attachment: | boost-fusion-issue2823-2.diff added |
---|
Updated patch to take Steven's suggestion.
comment:11 by , 7 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Took a look at the code and it looks like this is due to function call arguments being called in different orders on different platforms, so there's not much that can be done. I think that this really needs to be highlighted (at least mentioned) in the docs somewhere.
I could be wrong though, I'm not very good at reading PP-intensive code.