C++ Macros #ifdef

C++ Macros #ifdef

本文关键字:#ifdef Macros C++      更新时间:2023-10-16
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
}

如何在第一次调用testFunc((时将HERE的值打印为1,然后在第二次调用时将HERE的值打印成2。

对于我所拥有的当前代码,正在打印的值是-1。

缺少的是预处理器指令在编译时之前进行求值。

这意味着当预处理器解析你的代码时:

  1. 设置TEST1
  2. 取消设置TEST1
  3. 设置TEST2
  4. 取消设置TEST2
  5. 检查是否定义了TEST1(未定义(
  6. 检查是否定义了TEST2(未定义(
  7. 检查是否定义了HERE(未定义(

这意味着testFunc变成:

void testFunc() {
myval = -1;
}

然后,在这个预处理之后,您的代码就被编译了。

我会考虑使用预处理器之外的其他东西来实现您想要实现的目标。

按照您想要的方式,这是不可能的。宏是在编译之前进行评估的。它将简单地从上到下解析文档,并根据宏替换文本。当预处理达到testFunc时,TEST1TEST2都不再定义(您在代码的前面#undef都定义了(,所以您最终得到了

void testFunc()
{
myval = -1;
}

然后对其进行编译。看起来你想创建一个类似于模板函数的东西?也许实际的函数模板可以解决您的问题。

如何在第一次调用testFunc((时将HERE的值打印为1,然后在第二次调用时将HERE的值打印成2。

这就是预处理后您尝试的函数的样子:

void testFunc()
{
myval = -1;
}

正如您所看到的,该函数不接受任何形式的输入,并且总是无条件地为全局变量分配相同的值。

使用宏无法实现您想要的功能。


要根据调用函数的次数打印不同的值,可以使用函数对象。功能对象可以具有内部状态:

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

所有#语句都称为预处理器指令。这些是编译器的指令。您希望实际编译的代码能够维护程序运行时的某些状态。

有两种方法可以实现这一点,要么使用:

  1. 全局变量
  2. 静态变量

以下示例显示了这两种方法。每个函数也有一个内存值,它会被更新以记住该函数是否被调用过。

#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";
}

输出:

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