ant2009
ant2009

Reputation: 22656

#define, #ifdef #undef #endif

I have the following code

#define PROC_ADD

void main(void)
{
    while(1)
    {
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
    }
}

However, it will run the code. But it won't run the code in the else after the PROC_ADD has been undefined.

I think the reason could be that you can only define and undefine at compile time, and not at run-time. However, I am not really sure.

Upvotes: 3

Views: 14953

Answers (6)

Amarghosh
Amarghosh

Reputation: 59461

Think about it this way: the else portion of the following code is not executed, even though x has been set to false in the if section.

The condition is checked in the if(x) line itself. Once it enters that block, it doesn't recalculate each of the subsequent else sections. The compiler has already made a decision on that.

bool x = true;
if(x)
{
  // Do something
  x = false;
}
else
{
  // Else code
}

Upvotes: 2

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76611

You are doing the build time equivalent of:

int x = 1;

int main()
{
    if (x)
    {
        ...
        x = 0;
    }
    else
    {
        ...
    }
}

ifdef, etc. happen at build time, but for your example, that's not an issue. Once you evaluate the if (either the runtime or build-time form), the decision about which branch to take it made. Changing something after the decision has been made does not change that decision.

Upvotes: 5

AakashM
AakashM

Reputation: 63378

If you want the code represented by the second comment section to always run, just do

#ifdef PROC_ADD
// Do the stuff to be done if PROC_ADD is defined
#undef PROC_ADD
#endif
// Do the stuff to always be done

If you want run-time behaviour changes, you must use run-time constructs (such as a variable to serve as a flag). As we are all saying ;), pre-processor directives are evaluated once only, at compile time.

Upvotes: 2

Conrad Meyer
Conrad Meyer

Reputation: 2897

The ifdef condition is evaluated when the preprocessor gets to it. When you undef PROC_ADD inside the ifdef'd code, the preprocessor has already decided which section of code to include and which to ignore.

Furthermore, yes: ifdef, undef, etc are processed at pre-processing time -- the compiler never even sees these so-called directives. This of course means run-time code never sees these directives either.

The preprocessor works by taking a single pass through the text file. The preprocessor does not even care that your text file happens to contain C code! It has zero knowledge that your ifdefs and elses and whatnot happen to be inside a while loop.

Upvotes: 3

sharptooth
sharptooth

Reputation: 170549

#defines only work during preprocessing. So

#define PROC_ADD 
void main(void) 
{
#ifdef PROC_ADD 
// Do this code here then undefined it to run the code in the else 
// processing work 
#undef PROC_ADD 
#else 
// now that PROC_ADD has been undefined run this code 
// processing work 
#endif 
}

will be processed the following way: since PROC_ADDR is defined the preprocessor will completely exclude the #else branch and then execute #undef, so the #else branch code never survives preprocessing and never reaches the compiler.

Upvotes: 3

abyx
abyx

Reputation: 72998

In just about every programming language or syntax, once execution has entered one branch of a conditional (in this case, the conditional being #ifdef, even if the condition changes during execution of the branch, other branches will never be executed.

I'm sure you wouldn't expect this to print "Hello", would you?

if (i == 1)
    i = 0;
else
    printf("Hello\n");

Basically what you're saying is that the code under the else branch should always execute, then just take it out of a branch, and put it directly in the code.

Both the compiler and the execution only make one pass through conditionals, once a match has been found they look no further.

Upvotes: 2

Related Questions