Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get the C++ preprocessor to send output during compilation?

I have been debugging a particularly insidious bug which I now believe to be caused by unexpected changes which stem from different behavior when different headers are included (or not).

This is not exactly the structure of my code but let's just take a look at this scenario:

#include "Newly_created_header_which_accidentally_undefines_SOME_DEFINE.h"

// ...

#ifdef SOME_DEFINE
    code_which_i_believe_i_am_always_running();
#else 
    code_which_fails_which_i_have_forgotten_about(); // runtime error stack traces back here, but I don't know this... or maybe it's some strange linker error
#endif

I search through my git commits and narrow down the cause of the bug, compiling and running my code countless times, only to find after several hours that the only difference required for causing the bug is the inclusion of what appears to be a completely benign and unrelated header.

Perhaps this is a great argument for why the preprocessor basically just sucks.

But I like it. The preprocessor is cool because it lets us make shortcuts. It's only that some of these shortcuts, when not used carefully, bite us in the butt pretty hard.

So at this juncture it would have helped if I could use a directive like #echo "Running old crashy code" where I'll be able to see this during compilation so I could be tipped off immediately to start investigating why SOME_DEFINE was not defined.

As far as I know the straightforward way of determining if SOME_DEFINE is defined is to do something like

#ifndef SOME_DEFINE
    printf("SOME_DEFINE not defined!!\n");

This will surely get the job done but there is no good reason for this task to be performed at runtime because it is entirely determined at compile-time. This is simply something I'd like to see at compile-time.

That being said, in this situation, using the print (or log or even throwing an exception) may be an acceptable thing to do because I won't really care about slowing down or cluttering up the questionable code. But that doesn't apply if I have for instance two code paths both of which are important, and I just want to know at compile-time which one is being activated. I'd have to worry about running the code that does the preprocessor-conditioned print at the beginning of the program.

This is really just a long-winded way of asking the question, "Can I echo a string to the output during compilation by using a preprocessor directive?"

like image 461
Steven Lu Avatar asked Jun 26 '12 22:06

Steven Lu


People also ask

What does the preprocessor do in compilation?

The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control. In many C implementations, it is a separate program invoked by the compiler as the first part of translation.

Does preprocessor run before compiler?

the macros are expanded by preprocessor before running the compiler proper.

What is the role of preprocessor in C programming?

The C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be the inclusion of header files, macro expansions, etc.

What are the outputs of the preprocessor?

The preprocessor outputs one make rule containing the object file name for that source file, a colon, and the names of all the included files, including those coming from -include or -imacros command line options.


2 Answers

If you use the #error directive, the output will be printed directly and the compilation will stop:

$ make days_in_month
cc     days_in_month.c   -o days_in_month
days_in_month.c:2:2: error: #error "ugly!"
make: *** [days_in_month] Error 1
$ 

This might not be quite what you wanted, but it gets the job done quickly.

$ cat days_in_month.c
#include <stdio.h>
#error "ugly!"
...

If you wish processing to continue, you can use #warning:

$ make days_in_month
cc     days_in_month.c   -o days_in_month
days_in_month.c:2:2: warning: #warning "ugly!" [-Wcpp]
$ head days_in_month.c 
#include <stdio.h>
#warning "ugly!"
like image 74
sarnold Avatar answered Sep 30 '22 03:09

sarnold


Answer more in line with what I was looking for is here: https://stackoverflow.com/a/3826876/340947

Sorry @sarnold

like image 40
Steven Lu Avatar answered Sep 30 '22 03:09

Steven Lu