C++ Macro Expander - c++

Sometimes I run across quite complicated macros and I would like to view what they will expand to given the parameters (there are string concatenations in there as well). Is there by any chance a program out there that will expand the macros?
I am aware of the compiler flag -E but what about a single file (or preferably a single macro?)

Eclipse will expand macros if you mouse over them. For macros which include other macros, Eclipse can even step through the macro expansions one step at a time.
(You can use Eclipse for this even if you normally use another IDE.)

A few options are:
In GCC:
gcc -E filename.c
Using computers precompiler:
cpp filename.c
In visual Studio:
Right-click on the file on the Solution Explorer, goto Properties. Under Configuration Properties->C/C++->Preprocessor & "Generate Preprocessed File"

The C and C++ preprocessor is called cpp on most systems - you can use it directly:
cpp somefile.c
will preprocess somefile.c, expanding macros and write the results to standard output. If you are using the Microsoft compiler:
cl -E somefile.c
will do the same, assuming you have the compiler on your PATH.

Netbeans IDE allows you to view what a macro expands to by holding Ctrl+Alt and hovering/clicking a macro.

Related

How can I get the compiler tell me what file #define a value?

My code is linking against several other libraries that are also developed at my company, one of these libraries is redefining several values from errno.h, I would like to be able to fix this, however I am having trouble finding the exact file that is redefining these values, I am want to know if there is a way to make the compiler tell me when a file has defined a particular value.
You can probably do it by adding -include errno.h to the command line that builds the library in question. Here's a quick example. I have a C program called "file.c":
#define ESRCH 8
That's it - then I compile with:
cc -c -include errno.h file.c
And presto, a compiler warning:
file.c:1:1: warning: "ESRCH" redefined
In file included from /usr/include/errno.h:23,
from <command-line>:0:
/usr/include/sys/errno.h:84:1: warning: this is the location of the previous definition
That will tell you where your bad definitions are.
Have you tried searching with grep?
If you don't want to search through all your headers for the particular #define, you could use
#undef YOUR_MANIFEST_CONSTANT
after each #include in your source module and then start removing them from the bottom up and see where your definitions come from.
Also, your compiler may tell you that a #define has been redefined. Turn all your warnings on.
With GCC I did something similar with:
g++ input.cc -dD -E > cpp.out
-dD tells cpp to print all defines where they were defined. And in the cpp output there are also markers for the include file names and the line numbers.
It is possible that some environments, I'm thinking IDE's here, have configuration options tied into the "project settings" rather than using a configuration header. If you work with a lot of other developers in a place where this behavior is NOT frowned on then you might also check your tool settings.
Most compilers will tell you where the problem is, you have to look and think about what the diagnostic notification is telling you.
Short of that, grep/findstr on *nix/Windows is your friend.
If that yields nothing then check for tool settings in your build system.
Some IDE's will jump to the correct location if you right click on the usage and select 'go to definition'.
Another option if you're really stuck is a command line option on the compiler. Most compilers have an option to output the assembler they generate when compiling C++ code.
You can view this assembler (which has comments letting you know the relative line number in the C++ source file). You don't have to understand the assembler but you can see what value was used and what files and definitions were included when the compiler ran. Check your compiler's documentation for the exact option to use

strange catch clause... C++

What is this catch clause??
STD_CATCH_ALL_with_kMETHODID(...)
Its used in a python interpreter extension...
It's a macro so you need to look in your headers. An IDE should be able to go to its definition
or look at the after preprocesser expansion. -E command line option on gcc
How about right-click and select Go To Declaration (using Visual Studio). You may try Go To Definition as well. If you cannot find it, it means you need to include a header where this macro is defined.

How to figure out what value MSVC is using for a preprocessor macro

I'm attempting to use a /D compiler option on MSVC6 to define a string, but there's something weird about using double quotes around it. To debug this problem, it would be extremely helpful for me to be able to see what value the preprocessor is actually substituting into my code where the macro is expanded. Is there any way I can do this? I tried creating a Listing file with "assembly and source", but the source contains the original macro name and the ASM is some incomprehensible gibberish at that line. Is there a way to get the macro value at compile time?
Failing that (or perhaps more useful), how do I specify a string with the /D option? It needs to substitute into my source with double quotes around it, since I'm using it as a string literal.
Try one of the following options to CL.exe:
/E preprocess to stdout
/P preprocess to file
If you're building within Visual Studio, you can specify custom command-line options in one of the project property dialogs.
MSVC has a compiler flag that allows you to see the preprocessed source file with all the macros expanded, comments removed, etc. - the entire translation unit in terms of the actual code that will compile. Preprocessed output should give you the insight you're looking for regarding your macro expansion. More info here.
There's an option to pass to the compiler (/P) and it will write the preprocessor output into my_cpp_file.i where you can look at it.

Viewing compiler expanded code - C++

I learned that compiler will expand macros while compiling. Templates are also expanded at the compile time. Is there any way to see this expanded code? I am compiling using Visual Studio 2008.
any thoughts?
The VC++ compiler (cl.exe) supports a few command line switches for this:
/E preprocess to stdout
/P preprocess to file
/EP preproscess to stdout with no #lines
Additional command-line switches can be added in your project properties. In my version (VC2005), Configuration Options -> C/C++ -> Command Line -> Additional Options
The compiler doesn't actually do any of the macro expansion. That is the task of the pre-processor. It all appears as one step, but the compiler actually forks out to a separate pre-processor tasks and traps the output for you.
Templates are not "expanded" at compile time. They are instantiated on use during compile. The difference is that the compiler immediately generates object code for the template; there's no intermediate source code that comes out. You can't look at the instantiated template code as source, it's dumped out as assembly when it's needed.
If you have GCC you can also call the pre-processor directly using 'cpp' with the right arguments (mostly include paths and command line macro definitions). Others have answered for MSVC.
Note that /E in VC++ only expands preprocessor statements (that is, #include, #ifdef, #define etc.)
I am not aware of any modern compiler that allows to expand templates.
To emit the preprocessed code, call cpp directly of use the -E option in gcc and related compilers; I'm sure other compilers or suites have similar things (indeed as per the other answer it's /E or /P in VC++).
Not sure about outputting instantiated templates. That's much harder to do, I think, since it's actually part of compilation rather than preprocessing (at least in modern compilers, since the original cfront version which was a c++-to-c translator, if I recall correctly).
It's easy to add an option to compilers to show the output after macro substitution. That's defined as a simple text substitution option anyway. Many compilers implement this as a separate stage, sometimes even handled as a separate tool. In any case, the result of the macro substitution is a collection of Translation Units in text form.
Templates, on the other hand, are compiled. There are multiple stages to this. Names are resolved twice, for instance. In either stage, the compiler would store the result of the name lookup. That's a table entry. How would you show that in text form? There's no trivial C++ expression for that.

Is there a good general method for debugging C++ macros?

In general, I occasionally have a chain of nested macros with a few preprocessor conditional elements in their definitions. These can be painful to debug since it's hard to directly see the actual code being executed.
A while ago I vaguely remember finding a compiler (gcc) flag to expand them, but I had trouble getting this to work in practice.
gcc -E will output the preprocessed source to stdout.
For MSVC users, you can right-click on the file/project, view the settings and change the file properties to output preprocessed source (which typically in the obj directory).
This might not be applicable in your situation, but macros really do hamper debugging and often are overused and avoidable.
Can you replace them with inline functions or otherwise get rid of them all together?
You should probably start moving away form Macros and start using inline and templates.
Macros are an old tool, the right tool sometimes. As a last resort remember printf is your friend (and actually printf isn't that bad a friend when your doing multithreaded stuff)
Debug the dissasembly with the symbols loaded.
gcc -save-temps
will write out a .i (or .ii file for C++) which is the output of the C preprocessor, before it gets handed to the compiler. This can often be enlightening.
GCC and compatible compilers use the -E option to output the preprocessed source to standard out.
gcc -E foo.cpp
Sun Studio also supports this flag:
CC -E foo.cpp
But even better is -xdumpmacros. You can find more information in Suns' docs.