Search code examples
c++preprocessor-directive

#define used with operators


I know that #define has the following syntax: #define SYMBOL string If I write, for example

#define ALPHA 2-1
#define BETA ALPHA*2

then ALPHA = 1 but BETA = 0.(why ?)

But if i write something like this

#define ALPHA (2-1)
#define BETA ALPHA*2

then ALPHA = 1 and BETA = 2.

Can someone explain me what's the difference between those two ?


Solution

  • Pre-processor macros created using #define are textual substitutions.

    The two examples are not equivalent. The first sets BETA to 2-1*2. The second sets BETA to (2-1)*2. It is not correct to claim that ALPHA == 1 as you do, because ALPHA is not a number - it is a free man! it's just a sequence of characters.

    When parsed as C or C++, those two expressions are different (the first is the same as 2 - (1*2)).

    We can show the difference, by printing the string expansion of BETA as well as evaluating it as an expression:

    #ifdef PARENS
    #define ALPHA (2-1)
    #else
    #define ALPHA 2-1
    #endif
    
    #define BETA ALPHA*2
    
    #define str(x) str2(x)
    #define str2(x) #x
    
    #include <stdio.h>
    int main()
    {
        printf("%s = %d\n", str(BETA), BETA);
        return 0;
    }
    

    Compile the above with and without PARENS defined to see the difference:

    (2-1)*2 = 2
    2-1*2 = 0
    

    The consequence of this is that when using #define to create macros that expand to expressions, it's generally a good idea to use many more parentheses than you would normally need, as you don't know the context in which your values will be expanded. For example:

    #define ALPHA (2-1)
    #define BETA ((ALPHA)*2)