Good day,
I've faced with a strange problem while compiling very simple C++ program which leverages recursive macros expansion:
#define FINAL(a1, a2, a3) const char *p = "final values are: " #a1 " " #a2 " " #a3;
#define SPLIT(a1, a2) a1, a2
#define BRACES(a1, a2) ( a1, a2 )
#define START(macro, a1, a2) macro BRACES(a1, SPLIT a2)
START(FINAL, 1, (2, 3))
int main(int argc, char* argv[])
{
std::cout << p << std::endl;
return 0;
}
The program is expecting to print "final values are: 1 2 3" text. And it does on a Visual Studio 2008.
But I see an issue when trying to compile it with mingw32 gcc-6.3 on Windows 7 and with gcc-5.4 on Linux Ubuntu-16:
$ g++ -I /e/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60 test.cpp
test.cpp:7:24: error: expected constructor, destructor, or type conversion before '(' token
#define BRACES(a1, a2) ( a1, a2 )
^
test.cpp:8:36: note: in expansion of macro 'BRACES'
#define START(macro, a1, a2) macro BRACES(a1, SPLIT a2)
^~~~~~
test.cpp:12:1: note: in expansion of macro 'START'
START(FINAL, 1, (2, 3))
^~~~~
It looks like it doesn't depend on a C++ standard, I've tried -std=c++11 and -std=c++03 with gcc. I've reread part 16.3 "Macro replacement" of C++ 11 standard a few times, but I guess I've missed something important there.
What can be wrong here with the code?
One more important thing: BOOST_PP_SEQ_FOR_EACH_I_R from boost preprocessor library can't be compiled too, which is more than strange:
#include <iostream>
#include <boost/preprocessor/seq/for_each_i.hpp>
#define FINAL2(r, data, id, value) const char *p ## id = #value;
BOOST_PP_SEQ_FOR_EACH_I_R(_, FINAL2, _, (a)(b)(c))
int main()
{
std::cout << p1 << std::endl;
return 0;
}
Error output:
$ g++ -I /e/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60 -std=c++03 test2.cpp
In file included from test2.cpp:2:0:
E:/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60/boost/preprocessor/seq/for_each_i.hpp:96:96: error: expected constructor, destructor, or type conversion before '(' token
# define BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC(r, macro, data, seq) BOOST_PP_FOR_ ## r((macro, data, seq, 0, BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_FOR_EACH_I_P, BOOST_PP_SEQ_FOR_EACH_I_O, BOOST_PP_SEQ_FOR_EACH_I_M)
^
E:/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60/boost/preprocessor/control/iif.hpp:32:31: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_R_DETAIL_CHECK_EXEC'
# define BOOST_PP_IIF_1(t, f) t
^
E:/dev-libs/boost/boost_1_60_0-mingw32/include/boost-1_60/boost/preprocessor/control/iif.hpp:25:39: note: in expansion of macro 'BOOST_PP_IIF_1'
# define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_ ## bit(t, f)
^~~~~~~~~~~~~