Can the C preprocessor perform integer arithmetic?

The code you wrote doesn't actually make the preprocessor do any calculation. A #define does simple text replacement, so with this defined:

#define PI 3.1416
#define OP PI/100

This code:

if (OP == x) { ... }

becomes

if (3.1416/100 == x) { ... }

and then it gets compiled. The compiler in turn may choose to take such an expression and calculate it at compile time and produce a code equivalent to this:

if (0.031416 == x) { ... }

But this is the compiler, not the preprocessor.

To answer your question, yes, the preprocessor CAN do some arithmetic. This can be seen when you write something like this:

#if (3.141/100 == 20)
   printf("yo");
#elif (3+3 == 6)
   printf("hey");
#endif

Yes, it can be done with the Boost Preprocessor. And it is compatible with pure C so you can use it in C programs with C only compilations. Your code involves floating point numbers though, so I think that needs to be done indirectly.

#include <boost/preprocessor/arithmetic/div.hpp>
BOOST_PP_DIV(11, 5) // expands to 2
#define KB 1024
#define HKB BOOST_PP_DIV(A,2)
#define REM(A,B) BOOST_PP_SUB(A, BOOST_PP_MUL(B, BOOST_PP_DIV(A,B)))
#define RKB REM(KB,2)

int div = HKB;
int rem = RKB;

This preprocesses to (check with gcc -S)

int div = 512;
int rem = 0;

Thanks to this thread.


Integer arithmetic? Run the following program to find out:

#include "stdio.h"
int main() {
    #if 1 + 1 == 2
        printf("1+1==2\n");
    #endif
    #if 1 + 1 == 3
        printf("1+1==3\n");
    #endif
 }

Answer is "yes", there is a way to make the preprocessor perform integer arithmetic, which is to use it in a preprocessor condition.

Note however that your examples are not integer arithmetic. I just checked, and gcc's preprocessor fails if you try to make it do float comparisons. I haven't checked whether the standard ever allows floating point arithmetic in the preprocessor.

Regular macro expansion does not evaluate integer expressions, it leaves it to the compiler, as can be seen by preprocessing (-E in gcc) the following:

#define ONEPLUSONE (1 + 1)
#if ONEPLUSONE == 2
    int i = ONEPLUSONE;
#endif

Result is int i = (1 + 1); (plus probably some stuff to indicate source file names and line numbers and such).


YES, I mean: it can do arithmetic :)

As demonstrated in 99 bottles of beer.