Boost logo

Boost Users :

From: Martin Apel (martin.apel_at_[hidden])
Date: 2008-06-23 07:22:12


Hi all,

Steven Watanabe wrote:
> AMDG
>
> Martin Apel wrote:
>> I stumbled across something very strange related to
>> boost::mpl::for_each and numbered vectors and sets (as opposed to the
>> variadic forms). The program below contains a typelist with 21 (i.e.
>> more than BOOST_MPL_LIMIT_SET_SIZE) classes. This typelist is
>> converted to a typelist containing pointers to those classes. Finally
>> the main program calls for_each with that typelist to print the names
>> of the types. This works without problems on Linux and Windows. But now:
>> If you remove the include "boost/mpl/vector/vector30.hpp" everything
>> still compiles fine without warnings under both operating systems. On
>> Linux everything continues to work, whereas under Windows nothing is
>> printed anymore.
>
> I don't think that it should compile on windows. I assume that you
> are using msvc
> on Windows and gcc on Linux?
>
Yes, exactly.
>> for_each does not loop through the typelist for an unknown reason.
>> Everything works again, when reducing the number of classes to 20
>> (and adjusting the include to set20.hpp).
>> From my understanding BOOST_MPL_LIMIT_SET_SIZE and its brothers and
>> sisters should not have any impact on numbered sequences, only on
>> variadic ones. But still it looks as if something very strange is
>> happening here.
>
> Here's the result of the transform is on msvc 9.0
> boost::mpl::vector21<C21 *,C20 *,C19 *,C18 *,C17 *,C16 *,C15 *,C14
> *,C13 *,C12 *,C11 *,C10 *,C9 *,C8 *,C7 *,C6 *,C5 *,C4 *,C3 *,C2 *,C1 *>
>
> Without <boost/mpl/vector/vector30.hpp> the result is
> boost::mpl::push_back<boost::mpl::vector20<C21 *,C20 *,C19 *,C18 *,C17
> *,C16 *,C15 *,C14 *,C13 *,C12 *,C11 *,C10 *,C9 *,C8 *,C7 *,C6 *,C5
> *,C4 *,C3 *,C2 *>,C1 *>
>
> The reason? On compilers without typeof, including msvc, push_back on
> a vector0 gives
> a vector1, push_back on a vector1 gives a vector2, and so on. The
> unnumbered form
> is specialized for every possible number of arguments and inherits
> from the appropriate
> numbered form.
>
> Now for the strange part--when an mpl lambda expression is evaluated
> it checks to see
> whether the result of substituting placeholders is a metafunction, in
> other words it looks for
> a nested typedef ::type. If this is present, then it will return that
> typedef, otherwise, it
> will return type type unchanged. For example the expressions
> boost::mpl::apply<std::vector<_1>, int>::type evaluates to
> std::vector<int>.
> Now, if you don't #include <boost/mpl/vector/vector30.hpp>, there will be
> no specialization of push_back for vector20, thus mpl::lambda will think
> that the push_back is not a metafunction and return it unchanged.
>
> Finally, when mpl::begin and mpl::end are called on a type that is not
> an MPL sequence, they return mpl::void_. Since begin and end return
> the same type, for_each decides that it is dealing with an empty
> sequence.
>
Hm, typeof is not yet part of the C++ standard, as far as I know. This
means, that Boost MPL relies on non-standard behaviour to work correctly
(in this case).
What makes this very problematic is, that there is no error or warning,
simply different behaviour across platforms. This means I will have to
stumble through each
case, where the availability of the typeof operator makes a difference.
To me it looks, as if apply should not compile, if its argument is not a
metafunction. But I don't
have enough overview of the internal workings of MPL to estimate the
consequences of this.
Or is there any way to at least notice, that something is going wrong
without testing the software relying on MPL completely?

Regards,

Martin

____________
Virus checked by G DATA AntiVirus
Version: AVKB 18.318 from 23.06.2008


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net