0

I recently upgraded from Ubuntu 16.04 to 18.04 and since then part of my C++ code doesn't compile anymore (but this could also be just coincidence).

Here a minimal example of what isn't compiling:

#include <boost/test/unit_test.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
template<unsigned a, unsigned b> struct Tmpl { };
BOOST_FIXTURE_TEST_CASE( abc, Tmpl<1 BOOST_PP_COMMA() 1> ) { }

This is the error message of the gcc:

In file included from /home/ingo/opt/boost-1.68.0/include/boost/test/unit_test.hpp:19,
                 from min_ex.cpp:1:
min_ex.cpp:4:36: error: wrong number of template arguments (1, should be 2)
 BOOST_FIXTURE_TEST_CASE( abc, Tmpl<1 BOOST_PP_COMMA() 1> ) { }
                                    ^
/home/ingo/opt/boost-1.68.0/include/boost/test/unit_test_suite.hpp:142:27: note: in definition of macro ‘BOOST_FIXTURE_TEST_CASE_WITH_DECOR’
 struct test_name : public F { void test_method(); };                    \
                           ^
/home/ingo/opt/boost-1.68.0/include/boost/test/detail/pp_variadic.hpp:35:5: note: in expansion of macro ‘BOOST_TEST_INVOKE_VARIADIC’
     BOOST_TEST_INVOKE_VARIADIC(                                     \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ingo/opt/boost-1.68.0/include/boost/test/unit_test_suite.hpp:176:5: note: in expansion of macro ‘BOOST_TEST_INVOKE_IF_N_ARGS’
     BOOST_TEST_INVOKE_IF_N_ARGS( 2,                                     \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
min_ex.cpp:4:1: note: in expansion of macro ‘BOOST_FIXTURE_TEST_CASE’
 BOOST_FIXTURE_TEST_CASE( abc, Tmpl<1 BOOST_PP_COMMA() 1> ) { }
 ^~~~~~~~~~~~~~~~~~~~~~~
min_ex.cpp:3:41: note: provided for ‘template<unsigned int a, unsigned int b> struct Tmpl’
 template<unsigned a, unsigned b> struct Tmpl { };
                                         ^~~~
In file included from /home/ingo/opt/boost-1.68.0/include/boost/test/unit_test.hpp:19,
                 from min_ex.cpp:1:
/home/ingo/opt/boost-1.68.0/include/boost/test/unit_test_suite.hpp:163:20: error: expected primary-expression before ‘)’ token
         decorators );                                                   \
                    ^
/home/ingo/opt/boost-1.68.0/include/boost/test/detail/pp_variadic.hpp:27:51: note: in expansion of macro ‘BOOST_FIXTURE_TEST_CASE_WITH_DECOR’
 #  define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) tool (__VA_ARGS__)
                                                   ^~~~
/home/ingo/opt/boost-1.68.0/include/boost/test/detail/pp_variadic.hpp:35:5: note: in expansion of macro ‘BOOST_TEST_INVOKE_VARIADIC’
     BOOST_TEST_INVOKE_VARIADIC(                                     \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ingo/opt/boost-1.68.0/include/boost/preprocessor/control/iif.hpp:25:39: note: in expansion of macro ‘BOOST_PP_IIF_0’
 #    define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_ ## bit(t, f)
                                       ^~~~~~~~~~~~~
/home/ingo/opt/boost-1.68.0/include/boost/preprocessor/control/iif.hpp:18:37: note: in expansion of macro ‘BOOST_PP_IIF_I’
 #    define BOOST_PP_IIF(bit, t, f) BOOST_PP_IIF_I(bit, t, f)
                                     ^~~~~~~~~~~~~~
/home/ingo/opt/boost-1.68.0/include/boost/test/detail/pp_variadic.hpp:36:9: note: in expansion of macro ‘BOOST_PP_IIF’
         BOOST_PP_IIF(                                               \
         ^~~~~~~~~~~~
/home/ingo/opt/boost-1.68.0/include/boost/test/unit_test_suite.hpp:176:5: note: in expansion of macro ‘BOOST_TEST_INVOKE_IF_N_ARGS’
     BOOST_TEST_INVOKE_IF_N_ARGS( 2,                                     \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
min_ex.cpp:4:1: note: in expansion of macro ‘BOOST_FIXTURE_TEST_CASE’
 BOOST_FIXTURE_TEST_CASE( abc, Tmpl<1 BOOST_PP_COMMA() 1> ) { }
 ^~~~~~~~~~~~~~~~~~~~~~~

And I'm trying to compile using this command:

g++ -I/home/ingo/opt/boost-1.68.0/include -Wall -c -fmessage-length=0 -std=c++17 -MMD -MP -MF "min_ex.d" -MT "min_ex.o" -o "min_ex.o" "min_ex.cpp" 

I tried to find the error in the output of the preprocessor but for me it is quite hard to see anything there. The last two lines of the preprocessor output are:

template<unsigned a, unsigned b> struct Tmpl { };

struct abc : public Tmpl<1 { void test_method(); }; static void abc_invoker() { ::boost::unit_test::unit_test_log.set_checkpoint( ::boost::unit_test::const_string( "../src/test/min_ex.cpp", sizeof( "../src/test/min_ex.cpp" ) - 1 ), static_cast<std::size_t>(6), (::boost::wrap_stringstream().ref() << '"' << "abc" << "\" fixture ctor").str() ); abc t; ::boost::unit_test::unit_test_log.set_checkpoint( ::boost::unit_test::const_string( "../src/test/min_ex.cpp", sizeof( "../src/test/min_ex.cpp" ) - 1 ), static_cast<std::size_t>(6), (::boost::wrap_stringstream().ref() << '"' << "abc" << "\" fixture setup").str() ); boost::unit_test::setup_conditional(t); ::boost::unit_test::unit_test_log.set_checkpoint( ::boost::unit_test::const_string( "../src/test/min_ex.cpp", sizeof( "../src/test/min_ex.cpp" ) - 1 ), static_cast<std::size_t>(6), (::boost::wrap_stringstream().ref() << '"' << "abc" << "\" test entry").str() ); t.test_method(); ::boost::unit_test::unit_test_log.set_checkpoint( ::boost::unit_test::const_string( "../src/test/min_ex.cpp", sizeof( "../src/test/min_ex.cpp" ) - 1 ), static_cast<std::size_t>(6), (::boost::wrap_stringstream().ref() << '"' << "abc" << "\" fixture teardown").str() ); boost::unit_test::teardown_conditional(t); ::boost::unit_test::unit_test_log.set_checkpoint( ::boost::unit_test::const_string( "../src/test/min_ex.cpp", sizeof( "../src/test/min_ex.cpp" ) - 1 ), static_cast<std::size_t>(6), (::boost::wrap_stringstream().ref() << '"' << "abc" << "\" fixture dtor").str() ); } struct abc_id {}; static boost::unit_test::ut_detail::auto_test_unit_registrar abc_registrar60( boost::unit_test::make_test_case( &abc_invoker, "abc", "../src/test/min_ex.cpp", 6 ), 1> ); void abc::test_method() { }
mooha
  • 1
  • 1

1 Answers1

0

Just try to move the template definition to an additional typedef:

#include <boost/test/unit_test.hpp>
template<unsigned a, unsigned b> struct Tmpl { };

typedef Tmpl<1, 1> toto;
BOOST_FIXTURE_TEST_CASE( abc, toto ) { }

The problem comes from the , that is interpreted as a macro argument. Writing things this way is IMO much more readable that using the preprocessor library.

See this code in action here.

Raffi
  • 3,068
  • 31
  • 33