Subject: Re: [boost] [multi_array] Ticket#4874 "multi_array compile errors using Visual C++ 2010 in debug mode"
From: Thomas Klimpel (Thomas.Klimpel_at_[hidden])
Date: 2011-11-02 06:29:42
> -----Original Message-----
> From: boost-bounces_at_[hidden] [mailto:boost-
> bounces_at_[hidden]] On Behalf Of Stephan T. Lavavej
> Sent: Thursday, September 15, 2011 4:15 AM
> To: boost_at_[hidden]
> Subject: [boost] [multi_array] Ticket#4874 "multi_array compile errors
> using Visual C++ 2010 in debug mode"
> Hi Boost devs,
> VC10 users are occasionally encountering
> https://svn.boost.org/trac/boost/ticket/4874 and reporting it to MS.
> For example, see
> lation-issue-in-debug-mode-with-boost-library where I've explained
> what's going on (I wrote this analysis back in Feb 2010 and I believe
> it's still correct):
> The problem is that multi_array iterators report themselves as input
> iterators, which can't be written to (e.g. as the destination of a
> copy()). Under IDL=0, copy() doesn't actually care how its destination
> iterator is marked with an iterator category tag, it just tries to
> write to the destination iterator, and that works. Under IDL > 0,
> copy() wants to know whether its source and destination iterators are
> both random-access, in which case it can perform a range check and
> unwrap the destination iterator for increased performance. It does
> this by overloading foo(input_iterator_tag, output_iterator_tag) and
> foo(random_access_iterator_tag, random_access_iterator_tag) and calling
> foo(category(source), category(destination)). If both source and
> destination are random-access, both overloads are viable (i.e.
> callable) and the second overload is preferred, so it's actually
> called. Otherwise, source is required to be at least an input iterator
> (maybe stronger) and destination is
> required to be at least an output iterator (maybe stronger) so the
> first overload must be viable and the second overload will be non-
> viable, so the first overload wins by default.
> However, if the destination is not marked as an output iterator or
> stronger, then the first overload is non-viable as well as the second,
> so overload resolution fails and boom.
> Stephan T. Lavavej
> Visual C++ Libraries Developer
> Unsubscribe & other changes:
These failures are caused by a specific behavior of iterator_facade from Boost.Iterator, introduced by Jeremy Siek with the explanation "changed iterator_facade_default_category to stop lying about output_iterator_tag": <https://svn.boost.org/trac/boost/changeset/21683>.
I'm not the right person to judge (or understand) how serious the original code was a lying, but the attached patch that conditionally reintroduces the original behavior as a workaround for MSVC 10 fixes all compile failures.
However, the reason why I wrote this answer is that Jeffrey Lee Hellrung volunteered to help with the maintenance of Boost.Iterator:
I'm not saying that it must necessarily be fixed in Boost.Iterator. The problem could also be fixed by introducing some "lying" into Boost.Multi_Array, as has been done in other boost libraries to work around this issue. I would also be willing to provide the corresponding patches for "Boost.Multi_Array" that conditionally introduce lying for MSVC >=10.