cpreprocessor

Is there an easy one-line way to define a C preprocessor macro only if it doesn't already exist?


I have a file with hundreds of preprocessor macros of the form...

#define foo (bar)

Is there an easy one-line way to define each one only if it doesn't already exist?

For a single macro once could do the following...

#ifndef foo
#define foo (bar)
#endif

But I have hundreds of these macros. I was hoping for something like...

#define_if_not_defined foo (bar)

I actually tried creating my own macro

#define DEFINE_IFNDEF(foo,bar)\
    #ifndef foo\
    #define foo (bar)\
    #endif

Then I could just substitute... #define foo(bar) with DEFINE_IFNDEF(foo,bar)

But apparently there doesn't seem to be a good way to put preprocessor directives inside a preprocessor macro.

BACKGROUND

I was writing some safety certified code that had to replicate some functionality from a large preexisting library of several thousand files that wasn't safety certified.

There were several useful macro definitions in the original library scattered throughout a very large number of files. Including the whole files would become a huge expensive burden from a code review standpoint but including a few macros from some of the files to avoid re-inventing the wheel wasn't a problem. Therefore, I collected a lot of pre-processor macros here and there from a very large number of files in that original library and put them into one file.

My library has some major advantages in terms of smaller code size, faster speed, lower code complexity, and easier review safety wise but doesn't have every function that the original library had. So now some developers want to try and use the original library side by side with my code library.

The problem is that there are now hundreds of duplicate preprocessor macros that generate warnings. We would like to eliminate the warnings.

If all the macros came from the same header file, I could just use a #ifdef around the whole batch of them. But in my case, it's not so simple and I would need a lot of #ifdefs.


Solution

  • Easy! But not directly in C.

    Do a text file defines.txt like:

    DEF_A=123
    DEF_B=456
    

    And pass it through an external script make_defines.pl:

    #!/usr/bin/perl
    while(<>) {
       my ($def, $val) = split /=/;
       print "#ifndef $def\n#define $def $val#endif\n\n";
    }
    

    Now, you all you need is to run it:

    $ perl make_defines.pl defines.txt > defines.h
    

    You can also add it into makefile

    defines.h: defines.txt
        perl make_defines.pl $< > $@
    

    Done.