Boost logo

Boost Users :

Subject: [Boost-users] [Preprocessor] MSVC nonstandard macro expansion workaround?
From: rleigh_at_[hidden]
Date: 2016-03-03 08:49:58


Hi folks,

I've been trying to get Boost.Preprocessor to run a nested for loop over
two sequences to output nested switch blocks and case statements. This
works fine with GCC and clang. Unfortunately it's broken with MSVC. If
anyone had any thoughts on what I might need to tweak to enable the code
to work with MSVC, I'd be very appreciative. Even if it's as nasty as a
big ifdef with an alternative set of macros!

This is the test case:

--------
#include <boost/preprocessor.hpp>
#include <iostream>

#define LASERTYPE_VALUES
(EXCIMER)(GAS)(METALVAPOR)(SOLIDSTATE)(DYE)(SEMICONDUCTOR)(FREEELECTRON)(OTHER)

enum LaserType
{
   BOOST_PP_SEQ_ENUM(LASERTYPE_VALUES)
};

#define PP_SEQ_FOR_EACH_R_ID() BOOST_PP_SEQ_FOR_EACH_R
#define PP_DEFER(x) x BOOST_PP_EMPTY()

#define LT_NESTED(maR, maToplevelType, maNestedType)
\
   std::cout << "Test nested: first=" << LaserType(maToplevelType) << "
second=" << LaserType(maNestedType) << " \n";

#define LT_TOPLEVEL(maR, maUnused, maType)
\
   std::cout << "Test toplevel: " << LaserType(maType) << " \n";
\
   PP_DEFER(PP_SEQ_FOR_EACH_R_ID)()(maR, LT_NESTED, maType,
LASERTYPE_VALUES);

int main() {
   BOOST_PP_EXPAND(BOOST_PP_SEQ_FOR_EACH(LT_TOPLEVEL, %%,
LASERTYPE_VALUES));
}
--------

On MSVC, I get this:

> cl /EHsc /I \path\to\boost-1_60 /Fe:test-pp.exe test-pp.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.40629 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

test-pp.cpp
test-pp.cpp(22) : warning C4003: not enough actual parameters for macro
'BOOST_PP_VARIADIC_ELEM_3'
test-pp.cpp(22) : warning C4003: not enough actual parameters for macro
'BOOST_PP_BOOL'
test-pp.cpp(22) : warning C4003: not enough actual parameters for macro
'BOOST_PP_BOOL_I'
test-pp.cpp(22) : warning C4003: not enough actual parameters for macro
'BOOST_PP_VARIADIC_ELEM_2'
test-pp.cpp(22) : warning C4003: not enough actual parameters for macro
'BOOST_PP_DEC'
test-pp.cpp(22) : warning C4003: not enough actual parameters for macro
'BOOST_PP_DEC_I'
test-pp.cpp(22) : error C2065: 'BOOST_PP_SEQ_FOR_EACH_M' : undeclared
identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_TUPLE_EAT_2' : undeclared
identifier
test-pp.cpp(22) : error C2065: 'LT_NESTED' : undeclared identifier
test-pp.cpp(22) : error C2064: term does not evaluate to a function
taking 1 arguments
test-pp.cpp(22) : error C2146: syntax error : missing ';' before
identifier 'BOOST_PP_IIF_BOOST_PP_BOOL_'
test-pp.cpp(22) : error C3861: 'BOOST_PP_IIF_BOOST_PP_BOOL_': identifier
not found
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_3' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_TUPLE_EAT_4' : undeclared
identifier
test-pp.cpp(22) : error C2059: syntax error : ','
test-pp.cpp(22) : error C3861: 'BOOST_PP_EXPAND': identifier not found
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_4' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_5' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_6' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_7' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_8' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_9' : undeclared identifier
test-pp.cpp(22) : error C2065: 'BOOST_PP_FOR_10' : undeclared identifier

I've spent hours tweaking the testcase to try to make this work, but so
far without success. It doesn't help that I don't fully understand what
specifically is broken with the MSVC preprocessor, or how to work around
whatever is behaving in a non-stanadard way.

Many thanks,
Roger


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