Boost logo

Boost :

Subject: Re: [boost] [preprocessor metaprogramming] tools
From: paul Fultz (pfultz2_at_[hidden])
Date: 2012-07-05 12:07:50


I usually use the printf-style debugging for macros. So, if I want to see what the output is at a certain stage, I might add a `DEBUG()`, which is what I will look for in the preprocessor output. Heres an example, say we want to debug the TINY_size macros(taken from the C++ Template Metaprogramming appendix):     #define TINY_print(z, n, data) data     #define TINY_size(z, n, unused)                                 \       template <BOOST_PP_ENUM_PARAMS(n, class T)>                   \       struct tiny_size<                                             \           BOOST_PP_ENUM_PARAMS(n,T)                                 \           BOOST_PP_COMMA_IF(n)                                      \           BOOST_PP_ENUM(                                            \               BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none)      \       >                                                             \         : mpl::int_<n> {};     BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~)     #undef TINY_size     #undef TINY_print Now maybe I want to see what each of the parameters are getting passed into `TINY_size`, I can then change it to this:     #define TINY_size(z, n, unused)   DEBUG(z, n, unused)           \       template <BOOST_PP_ENUM_PARAMS(n, class T)>                   \       struct tiny_size<                                             \           BOOST_PP_ENUM_PARAMS(n,T)                                 \           BOOST_PP_COMMA_IF(n)                                      \           BOOST_PP_ENUM(                                            \               BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none)      \       >                                                             \         : mpl::int_<n> {}; Then I will look at the preprocessor output for `DEBUG(...)`. Now if I want to check that the subtraction is correct I could add another statement for that(or perhaps replace the the other debug statement):     #define TINY_size(z, n, unused)   DEBUG(z, n, unused)           \       DEBUG_SUB(BOOST_PP_SUB(TINY_MAX_SIZE,n))                      \       template <BOOST_PP_ENUM_PARAMS(n, class T)>                   \       struct tiny_size<                                             \           BOOST_PP_ENUM_PARAMS(n,T)                                 \           BOOST_PP_COMMA_IF(n)                                      \           BOOST_PP_ENUM(                                            \               BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none)      \       >                                                             \         : mpl::int_<n> {}; Then I look for `DEBUG_SUB(...)` in the preprocessor output. This works quite well for simple things like that, but when using recursion and deferred expressions, I have not found an effective way. This is because its difficult to tell why a macro didn't expand, is it because it was painted blue, or does it need another scan? In this case it requires an expert understanding of the preprocessor, and stepping through the expansions manually.  >I wanted to share with you something I've found very useful for >tracing/debugging macro metaprograms: the Eclipse CDT IDE has a >"macro stepper" that allows you to step through the expansion of >a macro step-by-step from the initial invocation to the final >expansion. (This feature can be accessed by using the "Explore >Macro Expansion" context menu item on a macro invocation.) This seems very nice, and probably can help especially when debugging deferred expressions. However, will it show when a macro is painted blue? That is really important to knowing why it didn't expand. Thanks, Paul


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk