[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 http://connect.microsoft.com/VisualStudio/feedback/details/687655/compilatio... 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. Thanks, Stephan T. Lavavej Visual C++ Libraries Developer

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost- bounces@lists.boost.org] On Behalf Of Stephan T. Lavavej Sent: Thursday, September 15, 2011 4:15 AM To: boost@lists.boost.org 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 http://connect.microsoft.com/VisualStudio/feedback/details/687655/compi 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.
Thanks, Stephan T. Lavavej Visual C++ Libraries Developer
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
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: <http://lists.boost.org/Archives/boost/2011/11/187491.php> 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. Regards, Thomas
participants (2)
-
Stephan T. Lavavej
-
Thomas Klimpel