Let's say we have a codebase that is used for many different costumers, and we have some code in it that is relevant only for costumers of type X. Is it better to use preprocessor directives to include this code only in costumer of type X, or to use if statements? To be clearer:

// some code
// do some things
// rest of the code


    // do some things

The arguments I can think about are:

  • Preprocessor directive results in smaller code footprint and less branches (on non-optimizing compilers)
  • If statements results with code that always compiles, e.g. if someone will make a mistake that will harm the irrelevant code for the project he works on, the error will still appear, and he will not corrupt the code base. Otherwise he will not be aware of the corruption.
  • I was always been told to prefer the usage of the processor over the usage of the preprocessor (If this is an argument at all...)

What is preferable - when talking about a code base for many different costumers?

  • 3
    What are the odds you'll ship a build not created using an optimizing compiler? And if it happens, will the impact matter (especially when put in context with all the other optimizations you'll miss then)?
    – user7043
    Nov 24, 2011 at 17:16
  • @delnan - The code is used for many different platforms with many different compilers. And regarding the impact - it might in certain cases.
    – MByD
    Nov 24, 2011 at 17:18
  • You were told to prefer something? That is like forcing someone to eat food from the KFC while he does not like chicken.
    – user4595
    Nov 24, 2011 at 21:31
  • @WTP - no I wasn't, I'm interested to know more, so I would make better decisions in the future.
    – MByD
    Nov 24, 2011 at 23:12
  • In your second example, is TYPE_X_CUSTOMER still a preprocessor macro?
    – detly
    Nov 25, 2011 at 1:15

5 Answers 5


I think there is one advantage of using a #define that you didn't mention, and that is the fact that you can set the value on the command line (thus, set it from your one-step build script).

Other than that, it is generally better to avoid macros. They don't respect any scoping and that can cause problems. Only very dumb compilers can't optimize a condition based on a compile-time constant. I don't know if that is a concern for your product (for example it might be important to keep the code small on embedded platforms).

  • Actually, this is for embedded systems
    – MByD
    Nov 24, 2011 at 17:29
  • The problem is that embedded systems are usually using some ancient compiler (like for example gcc 2.95). Nov 24, 2011 at 19:58
  • @VJo - GCC is the lucky case :)
    – MByD
    Nov 24, 2011 at 23:13
  • Try it out then. If it includes the unused code and that's a considerable size, then go for the defines. Nov 24, 2011 at 23:58
  • If you want to be able to set it via the compiler command line, I'd still use a constant in the code itself and only #define the value assigned to that constant. Nov 14, 2014 at 16:25

As for many questions, the answer of this question is it depends. Instead of saying which is better i have rather given examples and goals where a one is better than other.

Both preprocessor and constant have their own places of appropriate usage.

In case of pre-processor, the code is removed before the compile time. Hence, it is best suited for situations where code is expected not be compiled. This can affect the module structure, dependencies, and it may allow selecting best code segments for performance aspects. In following cases, one must divide code by use of preprocessor only.

  1. Multi-platform code:
    For example, when code is compiled under different platforms, when code has dependency on specific version numbers of OS (or even the compiler version - though this is very rare). For example when you are dealing with little-endien big-endien counterparts of code - they must be segregated with preprocessors rather than constants. Or if you are compiling code for Windows as well Linux and certain system calls are very different.

  2. Experimental Patches:
    Another case where this makes is to have a justified is some experimental code which is risky or certain major modules that needs to be omitted which will have significant linking or performance difference. The reason why one would want to disable the code via preprocessor rather than hiding under if() is because we might not be sure of bugs introduced by this specific change set and we are running under experimental basis. If it fails, we must do nothing else but disable that code in production than rewrite. Some time it is ideal to use #if 0 to comment out the entire code.

  3. Dealing with dependencies:
    Another reason where you may want to generate For example, if you don't want to support JPEG images, you can help get rid of compiling that module/stub and eventually library will not (statically or dynamically) link to that module. Sometimes packages run ./configure to identify availability of such dependency and if libraries are not present, (or user doesn't want to enable) such functionality is disabled automatically without linking with that library. Here it is always beneficial if these directives are auto generated.

  4. Licensing:
    One very interesting of example of preprocessor directive is ffmpeg. It has codecs which can potentially infringe patents by its use. If you download the source and compile to install, it asks you if you want or keep away such stuff. Keeping codes hidden under some if conditions still can land you in court!

  5. Code copy-paste:
    A.k.a macros. This is not an advice to over use macros - just that macros have much more powerful way to apply copy-past equivalent. But use it with great care; and use it if you know what you are doing. Constants of course, cannot do this. But one can use inline functions as well if that is easy to do.

So when do you use constants?
Almost everywhere else.

  1. Neater code flow:
    In general, when you use constants, it is almost indistinguishable from regular variables and hence, it is better readable code. If you write routine that is 75 lines- have 3 or 4 lines after every 10 lines with #ifdef is VERY unable to read. Probably given a primary constant governed by #ifdef, and use it in a natural flow every where.

  2. Well indented code: All preprocessor directive, never work well with otherwise well indented code. Even if your compiler does allow indentation of #def, Pre-ANSI C preprocessor did not allow for space between the start of a line and the "#" character; the leading "#" had to always be placed in the first column.

  3. Configuration:
    Another reason why constants/ or variables make sense is that they can easily evolve from being either linked to globals or in future can be extended to be derived from configuration files.

One last thing:
Never USE preprocessor directives #ifdef to #endif crossing the scope or { ... }. i.e. start of #ifdef or end of #endif on different sides of { ... }. This is extremely bad; it can be confusing, it can be sometime dangerous.

This of course, is not an exhaustive list, but shows you stark difference, where which method is more apt to use. It is not really about which is better, it is alway more of which one is more natural to use in given context.

  • Thanks for the long and detailed answer. I was aware to most of the things you mentioned and they were omitted from the question since the question is not whether to use preprocessor capabilities at all, but about a specific type of usage. But I think the basic point you made is true.
    – MByD
    Nov 25, 2011 at 0:29
  • 1
    "Never USE preprocessor directives #ifdef to #endif crossing the scope or { ... }" it depends on IDE. If IDE recognizes inactive preprocessor blocks and collapses them or shows with different color, it's not confusing.
    – Abyx
    Dec 1, 2011 at 13:06
  • @Abyx it is true that IDE may help. However, in many cases where people develop under *nix (linux etc.) platform - the choice of editors etc. are many (VI, emacs and so on). So someone else may be using a different editor than yours. Dec 2, 2011 at 6:35

Do your customers have access to your code? If yes, then preprocessor could be a better option. We have something similar and we use compile time flags for various customer (or customer specific features). Then a script could extract customer specific code and we ship that code. The customers are not aware of other customers or other customer specific features.


A few additional points worthy of mention:

  1. The compiler can process some kinds of constant expressions which the preprocessor cannot. For example, the preprocessor will generally have no way of evaluating sizeof() on non-primitive types. This may force the use of if() in some cases.

  2. The compiler will ignore most syntax issues in code which is skipped in #if (some preprocessor-related issues can still cause trouble) but insist upon syntactic correctness for code skipped with if(). Thus, if code which is skipped for some builds but not others becomes invalid as a consequence of changes elsewhere in the file (e.g. renamed identifiers) it will generally squawk on all builds if it's disabled with if() but not if it's disabled by #if. Depending upon why the code is being skipped, that may or may not be a good thing.

  3. Some compilers will omit unreachable code while others won't; declarations of static storage duration within unreachable code, however, including string literals, may allocate space even if no code can ever use the space thus allocated.

  4. Macros can use if() tests within them, but there is alas no mechanism for the preprocessor to perform any conditional logic within a macro [note that for use within macros, the ? : operator may often be better than if, but the same principles apply].

  5. The #if directive can be used to control what macros get defined.

I think if() is often cleaner for most cases except those which involve making decisions based upon what compiler is using, or what macros should be defined; some of the above issues may necessitate using #if, however, even in cases where if would seem cleaner.


Long story short: the fears about preprocessor directives are basically 2, multiple inclusions and maybe less readable code and a more criptic logic.

If your project is small with almost no big plan for the future, i think that both options offers the same ratio between pros and cons, but if your project is going to be huge, consider something else like the writing of a separate header file if you still want to use preprocessor directives, but keep in mind that this kind of approach usually makes the code less readable and be sure that the name of that constants means something for the business logic of the program itself.

  • This is a great code base, and the defines are in some separate headers indeed.
    – MByD
    Nov 24, 2011 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.