Boost logo

Boost Users :

Subject: Re: [Boost-users] Looping through variadic macro arguments
From: Florian Lindner (mailinglists_at_[hidden])
Date: 2016-03-30 04:35:50


Hey,

I have integrated the code in our project now and it fails to compile
with some older clang version.

It compiles fine with clang++ 3.7.1 and g++ 5.3.0 on my arch machine as
well as g++ 4.8.4 on our ubuntu server, but fails with clang++ 3.4 on
this machine as well as the travis

The complete compiler messages are at http://pastebin.com/HgjgCfsH it
is mostly something like that:

error: unknown type name 'BOOST_PP_IIF_0'
  assertion( reinterpret_cast<Vector&>(*this).size()==toAssign.size() );

The assertions code is at
https://github.com/precice/precice/blob/develop/src/utils/assertion.hpp

as well as all other code files.

If you want to give it a try, you can clone the project and use

clang++ -o
build/debug-nopetsc-nompi/tarch/configuration/ConfigurationRegistry.o
-c -Wall -std=c++11 -fPIC -Wsign-compare -g3 -O0 -DDebug -DAsserts
-DPRECICE_NO_PETSC -DEIGEN_INITIALIZE_MATRICES_BY_NAN -DPRECICE_NO_MPI
-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -Isrc -I/usr/include
-I/usr/include/python2.7 -I/usr/include/python2.7/numpy
src/tarch/configuration/ConfigurationRegistry.cpp

(it's also included in the pastebin above)

Do you have any idea?

Best,
Florian

On Tue, 29 Mar 2016 09:32:54 -0400
Edward Diener <eldiener_at_[hidden]> wrote:

> On 3/29/2016 6:49 AM, Florian Lindner wrote:
> >
> >
> > On Thu, 24 Mar 2016 11:00:57 -0400
> > Edward Diener <eldiener_at_[hidden]> wrote:
> >
> >> On 3/24/2016 4:42 AM, Florian Lindner wrote:
> >>>
> >>>
> >>> On Wed, 23 Mar 2016 11:56:25 -0400
> >>> Edward Diener <eldiener_at_[hidden]> wrote:
> >>>
> >>>> On 3/23/2016 11:45 AM, Florian Lindner wrote:
> >>>>> Hello,
> >>>>>
> >>>>> another question: I was expecting that the line
> >>>>>
> >>>>> BOOST_PP_SEQ_FOR_EACH_I(PRINT_ARGUMENT,,
> >>>>> BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__));
> >>>>>
> >>>>> in a macro #define vm(expr, ...) expands to nothing, when the
> >>>>> the macro is called with just one argument vm(false), but it
> >>>>> fails, only when called with just one argument:
> >>>>>
> >>>>> % g++ -std=c++11 -g3 test.cpp
> >>>>>
> >>>>> test.cpp: In function 'void f(int)':
> >>>>> test.cpp:109:51: error: expected primary-expression before '<<'
> >>>>> token std::cerr << " Argument " << i << ": " << elem <<
> >>>>> std::endl; ^
> >>>>> /usr/include/boost/preprocessor/seq/for_each_i.hpp:85:66: note:
> >>>>> in expansion of macro 'PRINT_ARGUMENT' # define
> >>>>> BOOST_PP_SEQ_FOR_EACH_I_M_I(r, macro, data, seq, i, sz) macro(r,
> >>>>> data, i, BOOST_PP_SEQ_HEAD(seq)) ^ test.cpp:140:1: note: in
> >>>>> expansion of macro 'assertion' assertion(!true);
> >>>>> ^
> >>>>>
> >>>>>
> >>>>> Is there any way to make it work like that?
> >>>>
> >>>> When you specify '...' to indicate variadic arguments you must
> >>>> always supply at least one argument. That's part of the C++
> >>>> standard.
> >>>>
> >>>> The way to make 'vm' work is to specify:
> >>>>
> >>>> #define vm(...)
> >>>>
> >>>> and then extract your first argument and pass the remaining
> >>>> arguments, if they exist, to your BOOST_PP_SEQ_FOR_EACH_I
> >>>> expansion. I will let you figure out how to do that, but if you
> >>>> find you can't figure it out post back and I will show you the
> >>>> code.
> >>>
> >>> Hey,
> >>>
> >>> ok, I used SEQ_TAIL for that and it works nicely:
> >>
> >> That's the solution.
> >>
> >> I could add a BOOST_PP_VARIADIC_TAIL but keeping the Boost PP
> >> variadic macros to a minimum was the idea when they were created.
> >>
> >>>
> >>> #define PRINT_ARGUMENT(r, data, i, elem) \
> >>> std::cerr << " Argument " << i << ": " << elem << std::endl;
> >>>
> >>> #define assertion(...) if (not BOOST_PP_VARIADIC_ELEM(0,
> >>> __VA_ARGS__)) { \
> >>
> >> Wouldn't
> >>
> >> if !(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)) { \
> >>
> >> be better ?
> >
> > The if condition needs to be enclosed by parens, don't it? This
> > piece of code does not compile?
>
> Yes, of course. My error ( wipes egg off face ).
>
> > Or do you propose to replace the "not" by "!"? I think they are the
> > same, I just like the "not" better, since it's more literal.
>
> OK. I rarely use the alphabetic alternatives to the logical operators.
>
> >
> >>
> >>> std::cerr << "Assertion in " << __FILE__ << ":" <<
> >>> __LINE__ \ << ", failed expression: " <<
> >>> BOOST_PP_STRINGIZE(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)) <<
> >>> std::endl; \ BOOST_PP_SEQ_FOR_EACH_I(PRINT_ARGUMENT,,
> >>> BOOST_PP_SEQ_TAIL(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))); \
> >>> std::cerr.flush();
> >>> \
> >>> std::cout.flush();
> >>> \
> >>> assert(false);
> >>> \ }
> >>>
> >>> as you can see, it's going to be an asssert macro. STRINGIZE gives
> >>> me the literal expression, like the # operator.
> >>>
> >>> Any comments?
> >>
> >> I'm glad Boost PP is useful to you <g>. If you are further
> >> interested in preprocessor programming in general you might find
> >> my Boost VMD library interesting ( shameless plug ) <g>.
> >
> > Thanks, I'll keep it in mind. But I try to keep preprocessor
> > programming to a minimum.
>
> Sure.
>
> There are some really neat things you can do using the preprocessor
> using Boost PP, and Boost VMD extends that realm when variadic
> parameters are available, as they are for all modern compilers.
>
> Both libraries are aids for more complicated C++ macro writing than
> normal.


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