-1

I need to explain for the MACRO define and if else conditions.

When I using the below function I get CHANGE value to 5

#include <stdio.h>

#define CHANGE var
int var;
int main()
{
    var = 5;
    printf("%d",CHANGE);

}

Output: 5

But if I use like this:

#include <stdio.h>

#define CHANGABLE_VALUE var
int var;
int main()
{
    var = 5;
    #if CHANGABLE_VALUE == 5
    printf("%d",CHANGABLE_VALUE);
    #else
    printf("There is no value");
    #endif



}

Output: There is no value

Why the #if statements not working ?

gogogo
  • 529
  • 1
  • 3
  • 11
  • 1
    Does this answer your question? [C preprocessor #if expression](https://stackoverflow.com/questions/6362622/c-preprocessor-if-expression) – kaylum Feb 02 '22 at 07:14
  • It's called _pre_ processor because it processes items before the rest of the compilation. That is, early on in the compile-time translation phases. It cannot be used for run-time evaluation. – Lundin Feb 02 '22 at 08:06

2 Answers2

3

Preprocessor definitions (aka Macros) are resolved during pre-compilation time, not during compilation time, and most certainly not during runtime, which seems to be what you're expecting.

Hence #if CHANGABLE_VALUE == 5 is replaced with #if var == 5 and then resolved as something which is false, so the actual code inside it is not even compiled (let alone executed).

  • If I use the #if var == 5 contidion, #else part is compile or not ? – gogogo Feb 02 '22 at 07:17
  • @gogogo: `var` is meaningless during pre-compilation, hence `var == 5` is evaluated as false, and the `#else` part is evaluated as true (hence the code inside it is compiled and added to the executable). –  Feb 02 '22 at 07:18
  • Thank you for your help. I am trying to reduce code compile size with #if #else statements. – gogogo Feb 02 '22 at 07:21
  • @gogogo: NP, keep in mind that those statements cannot use anything which is determined during runtime (it's a chicken/egg paradox - you cannot change the compiled code based on its output). –  Feb 02 '22 at 07:23
  • What is the meaning of "#if CHANGABLE_VALUE == var"? Now output: 5. – A4F9 Feb 02 '22 at 07:41
  • Compilation time and precompilation time are not separate in modern compilers such as GCC and Clang. Compiling a file containing the two lines `void a[3];` and `#error` with `clang -Wfatal-errors` will yield a message for the first line, showing this “compilation” error is recognized before the “precompilation” error. Explanations of preprocessing behavior should use the defined semantics, not chronology: Macro replacement never replaces the name of a variable with its value. When used in a `#if` directive, names not used in a `defined` test are replaced by `0`. – Eric Postpischil Feb 02 '22 at 12:54
1

There is a big difference between an #if preprocessor directive and a standard if statement. The preprocessor directive is evaluated before the code is actually compiled, whereas a standard if statement is evaluated at run-time.

Since

#if CHANGABLE_VALUE == 5

is false, the preprocessor will not include the line

printf("%d",CHANGABLE_VALUE);

in the code to be compiled. It will only include the #else part of the code, which is

printf("There is no value");

So, after the preprocessor phase is finished, your code will effectively look like this:

#include <stdio.h>

int var;
int main()
{
    var = 5;
    printf("There is no value");
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • This is very good explanation, thank you very much – gogogo Feb 02 '22 at 07:58
  • In modern compilers, compilation and preprocessing are integrated. Compiling a file containing the two lines `void a[3];` and `#error` with `clang -Wfatal-errors` will yield a message for the first line, showing this “compilation” error is recognized before the “preprocessor” error. Explanations of preprocessing behavior should use the defined semantics, not chronology: Macro replacement never replaces the name of a variable with its value. When used in a `#if` directive, names not used in a `defined` test are replaced by `0`. – Eric Postpischil Feb 02 '22 at 12:58