I\'ve got a pretty complicated macro inside my (unmanaged) C++ code. Is there any way to expand macros in VS debugger? Or maybe there is another way to debug macros there?
I heard all possible negative answers on the topic:
They are all true, but IMO they collide with the reality of everydays programming.
In fact, working on old C project, where macros were mostly simply used as functions, this became of crucial importance for me. Generating all preprocessed files with /P works, but is overkilling and time consuming. I just needed a tool that expands a simple macro defined a few lines above or at maximum in other file.
How to do that?
So, Yes, in a practical sense, it is possible.
Have I said that the macros are very complicated? I'd like to expand one or two layers only, not all macros (otherwise it is plainly unreadable)... while debugging
If there are not way too many macros you don't want to expand, then you can simply #undef them before the snippet you want to debug. Then compile with the [Generate Preprocessed File] as mentioned above. The compilation will fail but you will get a usable snipped in the preprocessed output with the correct expansions. Copy-paste, remove the #undef-s and debug.
Sadly, your best friends for dealing with C-style macros are inline, template and a good optimizing compiler.
Use inline functions (force inlining if you really mean it) and stick to it! This will be more efficient (get only inlined if it brings performance if you optimize for perf) and maintainable. You loose much by using macros: type checking & safety.
Macros do not exist for the compiler, they only do for the preprocessor. This one makes text replacements without looking for side effects. So macros are actually never called and you cannot debug into them. No matter how you code a macro, misuse is always possible. Like in this example:
#define SQUARE(a) ((a)*(a))
Note already the (
`)´ to protect against replacements like SQUARE(3+2). But they do not protect against:
int a = 1;
int b = SQUARE(++a);
One would expect it to be 4 but you end up with 6 which is not really square. As it expands to int b = (++a)*(++a);
You wouldn't have this trouble with inlined functions.
Note that the implementation of an inlined function has to be visible for the compiler at the places where you use it. Also debugging will be weird to the novice user: as there are many instances of an inlined function, you'll get a huge list of methods if you want to move the execution point to another place for example.