1
#include <stdio.h>

#define ONE 3 > 2 ? 16 : 64
#define TWO ONE/16

int main () {  
    printf("%d\n", TWO);
    return 0;
}

I write two #define, but output is 16, while I expected it was 1. Why does this happen?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    Take a look at the preprocessor output (`-E` command line option for GCC). – Evg Sep 16 '21 at 08:22
  • 3
    The preprocessor must not be used for that. Make constants and functions. You're just barely scratching the surface of why in this small example. `constexpr auto ONE = 3 > 2 ? 16 : 64;` would have worked like you expect. – spectras Sep 16 '21 at 08:23
  • 1
    You'd better understand how preprocessors work, because this will turn out to be `printf("%d\n", 3 > 2 ? 16 : 64/16)`, which is clearly not going to print `1` . Creative (and arguably proper) use of *parenthesis* in your preprocessor macro usages will give you what you seem to seek. – WhozCraig Sep 16 '21 at 08:23
  • `#define` can be used iteratively, but you do need to use parens properly. It appears the code snippet is in C and not C++, because the C header file is `` and the C++ header file is ``. – Eljay Sep 16 '21 at 09:02

2 Answers2

2

Macros are a simple text replacement. When preprocessor goes through the code, it replaces

printf("%d\n", TWO);

with

printf("%d\n", ONE/16);

and then with

printf("%d\n", 3 > 2 ? 16 : 64/16);

Then compiler can see that ternary operator condition evaluates to true and takes the first result - 16.


You probably wanted first macro to be wrapped in parentheses:

#define ONE (3 > 2 ? 16 : 64)

But I'd strongly suggest to avoid using macros wherever possible. As comments suggest,

constexpr auto ONE = 3 > 2 ? 16 : 64;

would give you the expected result.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
1

The preprocessor is only a simple text replacing.

If you replace it by hand or simply use the gcc -E option ( maybe different on other compilers ) you get:

#define TWO 3 > 2 ? 16 : 64/16

What you expect is can be simply achieved by using braces:

#define ONE (3 > 2 ? 16 : 64)
#define TWO ONE/16

BTW: You should not longer use macros at all and replace it by compile time constant expressions like:

constexpr auto ONE = 3 > 2 ? 16 : 64;

The benefit is, that you get errors or warnings if you did something wrong and all expressions are type safe. Macros, as said, are only doing text replacement without any syntax check for the later on used language.

Klaus
  • 24,205
  • 7
  • 58
  • 113