简体   繁体   中英

C++ Macros #ifdef

void testFunc();

int myval = 0;

int main()
{
    int a = 1;

    if (a > 0)
    {
        #define TEST1
        testFunc();
        #undef TEST1
    }

    int b = 2;
    if ( b > 0)
    {
        #define TEST2
        testFunc();
        #undef TEST2
    }

    std::cout << "val : " << myval << endl;

    getchar();

    return 0;
}


void testFunc()
{

#ifdef TEST1
#define HERE 1
#endif

#ifdef TEST2
#define HERE 2
#endif

#ifdef HERE
    myval = HERE;
#else
    myval = -1;
#endif

}

How can I print the value of HERE to be 1 when testFunc() is called first time and then print the value of HERE to be 2 when it is called second time.

With the current code that I have, the value that is being printed is -1.

What you're missing is that the preprocessor directives evaluate before compile time.

That means that as the preprocessor parses your code it:

  1. Sets TEST1
  2. Unsets TEST1
  3. Sets TEST2
  4. Unsets TEST2
  5. Checks if TEST1 is defined (it isn't)
  6. Checks if TEST2 is defined (it isn't)
  7. Checks if HERE is defined (it isn't)

That means testFunc becomes:

void testFunc() {
    myval = -1;
}

And then, after this preprocessing, your code is compiled.

I would consider using something other than the preprocessor to accomplish what you are trying to achieve.

How can I print the value of HERE to be 1 when testFunc() is called first time and then print the value of HERE to be 2 when it is called second time.

This is what your attempted function looks like after pre-processing:

void testFunc()
{
    myval = -1;
}

As you can see, the function doesn't take any form of input, and always unconditionally assigns the same value to the global variable.

You cannot achieve what you want with macros.


To have the behaviour of printing different value depending on how many times you call a function, you could use a function object instead. Function objects can have internal state:

auto testFunc = [HERE = 1]() mutable {
    return HERE++;
};
std::cout << testFunc(); // prints 1
std::cout << testFunc(); // prints 2

The way you intent to do it, it's not possible. Macros are a evaluted before compilation. It will simply parse the document from top to bottom and replace text according to the macros. When the pre-processing reaches testFunc , both TEST1 and TEST2 are not defined anymore (you #undef both earlier in the code), so you end up with

void testFunc()
{
    myval = -1;
}

which is then compiled. It looks like you want to create something like a template function? Maybe actual function templates can solve your problem.

All of # statements are called preprocessor directives. These are instructions to the compiler. You want the actually compiled code to maintain some state about the runtime of the program.

Two ways you could accomplish this are either using:

  1. Global variable
  2. Static variable

The following example shows both approaches. Each function also has a memory value which is updated to remember if the function has ever been called.

#include <iostream>

bool g_ran_already = false;

int first_different_global()
{
    if (!g_ran_already)
    {
        g_ran_already = true;
        return 1;
    }
    else
    {
        return 2;
    }
}

int first_different_static()
{
    static bool s_ran_already = false;

    if(!s_ran_already)
    {
        s_ran_already = true;
        return 1;
    }
    else
    {
        return 2;
    }
}

int main(int argc, char** argv)
{
    std::cout << "first_different_global() run 1: " << first_different_global() << "\n";
    std::cout << "first_different_global() run 2: " << first_different_global() << "\n";
    std::cout << "first_different_global() run 3: " << first_different_global() << "\n";
    std::cout << "first_different_static() run 1: " << first_different_static() << "\n";
    std::cout << "first_different_static() run 2: " << first_different_static() << "\n";
    std::cout << "first_different_static() run 3: " << first_different_static() << "\n";
}

Output:

first_different_global() run 1: 1
first_different_global() run 2: 2
first_different_global() run 3: 2
first_different_static() run 1: 1
first_different_static() run 2: 2
first_different_static() run 3: 2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM