229

Let's say I have a source file with many preprocessor directives. Is it possible to see how it looks after the preprocessor is done with it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Geo
  • 93,257
  • 117
  • 344
  • 520

10 Answers10

169

cl.exe, the command line interface to Microsoft Visual C++, has three different options for outputting the preprocessed file (hence the inconsistency in the previous responses about Visual C++):

If you want to preprocess to a file without #line directives, combine the /P and /EP options.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
bk1e
  • 23,871
  • 6
  • 54
  • 65
  • 1
    How do I pass these commands to a project with nmake and Makefile? – WooDzu Mar 09 '14 at 08:00
  • @WooDzu Use NMAKE (nmake.exe) to automate tasks that build Visual C++ projects by using a traditional makefile. ~ https://msdn.microsoft.com/en-us/library/f35ctcxw.aspx – G.Rassovsky Mar 17 '15 at 09:11
  • 8
    Please note that `/P` will suppress the generation of obj files. So if you put `/P` options, you may get link a error saying some obj files cannot be found because it is actually not generated at all. – smwikipedia Aug 09 '16 at 02:16
  • Make sure you are in `VS Developer command prompt` and NOT in `Command prompt` when trying to use MS compiler (`cl`). Compiler is not available in conventional comand prompt. – dmytro.poliarush Dec 25 '19 at 11:30
  • VS2019 Community: The [/P LNK 1104](https://developercommunity.visualstudio.com/comments/888419/view.html) error is still hot off the press. – Laurie Stearn Jan 17 '20 at 08:42
124

Most compilers have an option to just run the preprocessor. e.g., gcc provides -E:

   -E  Stop after the preprocessing stage; do not run the compiler proper.  
       The output is in the form of preprocessed source code, which is sent
       to the standard output.

So you can just run:

gcc -E foo.c

If you can't find such an option, you can also just find the C preprocessor on your machine. It's usually called cpp and is probably already in your path. Invoke it like this:

cpp foo.c

If there are headers you need to include from other directories , you can pass -I/path/to/include/dir to either of these, just as you would with a regular compile.

For Windows, I'll leave it to other posters to provide answers as I'm no expert there.

Todd Gamblin
  • 58,354
  • 15
  • 89
  • 96
112

Right-click on the file on the Solution Explorer, goto Properties. Under Configuration Properties->C/C++->Preprocessor, "Generate Preprocessed File" is what you are looking for. Then right-click on the file in the Solution Explorer and select "Compile". The preprocessed file is created in the output directory (e.g. Release, Debug) with an extension .i (thanks to Steed for his comment).

phonetagger
  • 7,701
  • 3
  • 31
  • 55
Jim Buck
  • 20,482
  • 11
  • 57
  • 74
  • 10
    "Preprocess to a File" in VS2010. – Rob W Nov 01 '13 at 09:31
  • 21
    BTW, the file is created in output directory (e.g. `Release`, `Debug`) with an extension `.i`. – Steed Jan 10 '14 at 11:05
  • 2
    This helps a lot since it uses the build configuration already set up in the project to find all the right headers. – IanH Nov 06 '15 at 19:45
  • 3
    Note, for me on MSVC 2015, the .i file was not in the **Output Directory**, but in the project's **Intermediate Directory**. These are not the same if you e.g. generate your projects using CMake. – user1556435 Dec 18 '17 at 16:39
21

You typically need to do some postprocessing on the output of the preprocessor, otherwise all the macros just expand to one liners, which is hard to read and debug. For C code, something like the following would suffice:

gcc -E code.c | sed '/^\#/d' | indent -st -i2 > code-x.c

For C++ code, it's actually a lot harder. For GCC/g++, I found this Perl script useful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ididak
  • 5,790
  • 1
  • 20
  • 21
8

I don't know anything about Microsoft compiler, but on GCC you can use this:

gcc -E -P -o result.c my_file.h

If you want to see comments use this:

gcc -E -C -P -o result.c my_file.h

More options avaliable on this page.

dzav
  • 545
  • 1
  • 10
  • 25
8

Try cl /EP if you are using Microsoft's C++ compiler.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Atempcode
  • 397
  • 1
  • 4
  • First of all this answer completely fails to mention where the preprocessed output goes. And then on modern versions of `cl.exe` you'll probably want several switches similar to this `cl /nologo /Zc:preprocessor /E /PD bla.cpp`, where `bla.cpp` can be created as an "empty" file by saying `echo.>bla.cpp` on the command prompt. – 0xC0000022L Jul 07 '22 at 13:49
6

As bk1e and Andreas M. answered, the /P option for the compiler will cause it to preprocess a file. However, in my project using VS2005 and Platform Builder (for an embedded ARM processor), the project did not present an option in the dialog box (as described by Jim B) to enable that option.

I could run CL manually and add /P, but it failed because I did not know all of the appropriate command-line options that were invisibly being activated by Platform Builder during the full build. So I needed to know all of those options.

My solution was to go look in the build.log file, and find the line that executed

CL blah-blah-blah myfile.c

I copied this line to the clipboard. The "blah-blah-blah" part contained the build options, and was huge.

Back in the IDE, I right-clicked on myfile.c, chose "Open Build Window", and then in that window I pasted the build command-line, and added a "/P".

CL /P blah-blah-blah myfile.c

Done. The myfile.i file was produced, which contained the preprocessor output.

Sam Pittman
  • 61
  • 1
  • 1
5

In Visual Studio you can compile a file (or project) with /P.

Andreas Magnusson
  • 7,321
  • 3
  • 31
  • 36
2

CPIP is a new C/C++ preprocessor written in Python. If you want a detailed visual representation of a preprocessed file, give it a shot.

CPIP is a C/C++ pre-processor implemented in Python. Most pre-processors regard pre-processing as a dirty job that just has to be done as soon as possible. This can make it very hard to track down subtle defects at the pre-processing stage as pre-processors throw away a lot of useful information in favor of getting the result as cheaply as possible.

Few developers really understand pre-processing, to many it is an obscure bit of black magic. CPIP aims to improve that and by recording every detail of preprocessing so CPIP can can produce some wonderfully visual information about file dependencies, macro usage and so on.

CPIP is not designed to be a replacement for cpp (or any other established pre-processor), instead CPIP regards clarity and understanding as more important than speed of processing.

Community
  • 1
  • 1
thegreendroid
  • 3,239
  • 6
  • 31
  • 40
2

On Windows OS, a simple one line answer to this question is to use the below command in DOS prompt to see the preprocessed file:

CL /P /C myprogram.c

This will generate a file called myprogram.i. Open it and look out for your expanded preprocessors.

manty
  • 287
  • 5
  • 19