0

I wrote a code in cpp. I have a loop in my code which have to execute in specified frequency. I want whenever the choosen frequency equal or more than 70hz an "if" statement to work, and whenever not the content of if executes without "if", but I don't know how to write it in as preprocessor. I wrote something like this but it always executes "else" part of this:

    #define Freq70Hz 70
    int frequency = Freq70Hz;
    int main
    { 
        while(true)
        {
            #if frequency == Freq70Hz 
             if(condition ){
             // do the firstthing
             }
            #else 
            // do the firstthing
            #endif

        }
    }
5
  • Won't frequency == Freq70Hz always be true? Commented Sep 11, 2014 at 11:32
  • Why can't you just say if(frequency == 70)? Commented Sep 11, 2014 at 11:33
  • Just use if( frequency == Freq70Hz && condition ) {} Why do you want to overcomplicate it? Commented Sep 11, 2014 at 11:34
  • Use if-else operators instead of preprocessor's commands. That will be better idea. Commented Sep 11, 2014 at 11:37
  • each time for changing the frequency i have to compile the code again. as result for the frequency lower than 70hz i don't want to compile the "if" so i wanna put it in #if to be preprocessored. be cause it take more cycle from my micro controller (i working on arm)to check this "if" when it has not execute. Commented Sep 11, 2014 at 14:57

4 Answers 4

4

Here you are mixing static, compile time programming with dynamic, run time programming. In this case, how would the preprocessor know the value of frequency at compile-time? It could change during the execution of the program. You either want to have a static solution like this:

#define FREQUENCY 70 //this can be changed by passing in compiler options
int main()
{ 
    while(true)
    {
#if FREQUENCY > 70
        if(condition ){
            // do the firstthing
        }
#else 
        // do the firstthing
#endif

    }
}

Or you want a dynamic solution like this:

int frequency = 70;
int main()
{ 
    while(true)
    {
        if(frequency == 70 && condition)
        {
            // do the firstthing
        }
        else
        {
            // do the firstthing
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

The second comment should probably be "do the second thing" each time.
It probably should be, but I left it as in his question for sake of consistency.
2

You are misunderstanding what the preprocessor does.

The preprocessor does text processing, before the program runs.

In particular, it sees normal variables only as text and has no idea what their types are or values will be at run time. That's true even if they are global variables like your frequency which is initialized when the program starts. We see that; the preprocessor doesn't.

What looks like an alias definition in #define Freq70Hz 70 is just a text replacement rule for the remaining part of the file. The text ("Freq70Hz") will be replaced (by "70") whenever it appears in the rest of the program -- but before the compiler sees the code.

Then you fall victim to a quirk of the preprocessor spec.

You think that the line #if frequency == Freq70Hz is meaningfully evaluated. You hope that the value of the variable frequency, which we (but not the preprocessor!) know to be 70, will be taken into account. But that's not what happens.

The preprocessor sees the preprocessor token frequency. It has no notion of frequency being an int variable, because it cannot understand the C programming language. It sees that this token is part of a conditional preprocessor expression. It has not been told to replace it with a value though.

Now the catch: Identifiers which are still there after all replacements have been performed in a preprocessor conditional expression are replaced with 0 (!), cf. latest C draft n1570, 6.10.1./4. The preprocessor does not complain about "undefined identifiers". This makes the directive #if frequency == Freq70Hz #if 0 == 70, which obviously is always false.

Since this default use of undefined preprocessor identifiers is a dangerous feature -- normal programming languages stopped doing that after Basic --, it's worth knowing a trick somebody showed me long ago: Use macro functions. #define Freq70Hz() 70 will be functionally equivalent but complain when you misspell it later.

Comments

0

Using dead code elimination with templates

template<bool isGE70Hz>
void DoWhile() {
    while(true) {
        if (isGE70Hz) { // dead code elimination as isGE70Hz is compiletime constant.
            if(condition ){
                // do the firstthing
            } 
        } else {
            // do the firstthing
        }
    }
}

int main() {
    if (frequency >= Freq70Hz) // chose specialization
        DoWhile<true>()
    else
        DoWhile<false>()
    // if frequency and Freq70Hz both are compiletime constants you could do
    // DoWhile<frequency >= Freq70Hz>
}

Comments

0

Assuming // do the firstthing is the SAME in both and assuming frequency is supposed to not change in your execution, I wouldn't use the pre-processor for this... if you use static const int frequency = Freq70Hz then later do:

    while(true)
    {
       if(condition || frequency == Freq70Hz){
         // do the firstthing
       }
    }

The compiler will compile out the appropriate thing based on the knowledge that frequency won't change. That is, if frequency == Freq70Hz then the whole if part won't be in a release executable. If frequency != Freq70Hz then the if part will just be the condition.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.