gpt4 book ai didi

c++ - Visual C++ 中的预处理器工具 __COUNTER__

转载 作者:可可西里 更新时间:2023-11-01 18:36:18 24 4
gpt4 key购买 nike

我需要在编译时在整个代码中生成一系列序列号。我以这样的方式尝试了“__COUNTER__”:

void test1()
{
printf("test1(): Counter = %d\n", __COUNTER__);
}
void test2()
{
printf("test2(): Counter = %d\n", __COUNTER__);
}
int main()
{
test1();
test2();
}

结果和我预想的一样完美:

test1(): Counter = 0
test2(): Counter = 1

然后我将“__COUNTER__”分散到不同的 .cpp 文件中:

In Foo.cpp:
Foo::Foo()
{
printf("Foo::Foo() with counter = %d\n", __COUNTER__);
}
In Bar.cpp:
Bar::Bar()
{
printf("Bar::Bar() with counter = %d\n", __COUNTER__);
}

In Main.cpp:
int main()
{
Foo foo;
Bar bar;
}

结果是:

Foo::Foo() with counter = 0
Bar::Bar() with counter = 0

在我看来,“__COUNTER__”是作为每个编译单元变量提供的。

我想要的是一个在整个代码中都有效的全局计数器。

这用于在我想要实现此目标的调试版本中进行测试:

想象一下,我在整个代码中都有 try/catch block (多个 .cpp 文件中的子系统或模块)。在运行时程序在循环中运行,在每个循环中所有的 try block 将按顺序执行(顺序无关紧要),我想测试代码如何对每个 try/catch 的异常使用react,逐个。例如,循环中的第一次,#1 try/catch block 抛出异常;第二次在循环中,#2 try/catch block 抛出异常,等等。

我计划有一个这样的全局计数器:

int g_testThrowExceptionIndex = 0;

在每个 try/catch 中:

try
{
TEST_THROW_EXCEPTION(__COUNTER__)
//My logic is here...
}
catch(...)
{
//Log or notify...
}

宏会是这样的:

#define TEST_THROW_EXCEPTION(n) \
if(g_testThrowExceptionIndex == n)\
{\
g_testThrowExceptionIndex++;\
throw g_testThrowExceptionIndex;\
}\

没有在编译时生成序列号的能力,我不得不这样写宏:

TEST_THROW_EXCEPTION(THROW_INDEX_1)
......
TEST_THROW_EXCEPTION(THROW_INDEX_N)

在标题中,定义:

#define THROW_INDEX_1 0
#define THROW_INDEX_2 1
......

问题是,每次添加 try/catch block 并要测试时,都必须通过 #define 创建一个新常量并将该数字放入宏中。更糟糕的是,如果您从代码中删除了一些 try/catch block 怎么办?你也必须更新你的#define 列表......

==============

解决方法:感谢 Suma 的想法,我最终得到了这样的结果:

#if defined(_DEBUG)  && defined(_EXCEPTION_TEST)
extern int g_testThrowExceptionIndex;
struct GCounter
{
static int counter; // used static to guarantee compile time initialization
static int NewValue() {return counter++;}
};
#define TEST_THROW_EXCEPTION \
static int myConst = GCounter::NewValue();\
if(g_testThrowExceptionIndex == myConst)\
{\
g_testThrowExceptionIndex++;\
throw 0;\
}
#else
#define TEST_THROW_EXCEPTION
#endif

在 main.cpp 中:

#if defined(_DEBUG) && defined(_EXCEPTION_TEST)
int g_testThrowExceptionIndex= 0;
int GCounter::counter= 0;
#endif

然后您可以将“TEST_THROW_EXCEPTION”放入您想要测试的任何 try/catch block 中。

最佳答案

您不能使用预处理器执行此操作,因为每个编译单元都是单独预处理的。为此需要一个运行时解决方案。您可以创建一个全局单例,每个需要唯一标识符的地方都可以使用该单例定义一个静态整数。

struct GCounter
{
static int counter; // used static to guarantee compile time initialization
static int NewValue() {return counter++;}
};

int GCounter::counter = 0;

void Foo1()
{
static int ID1 = GCounter::NewValue();
}

void Foo2()
{
static int ID2 = GCounter::NewValue();
}

注意:多个编译单元中那些静态值(ID)的初始化顺序是没有定义的。您可以确定它们将始终是唯一的,但您不能依赖它们具有某些特定的值或顺序。因此,当例如将它们保存到一个文件中 - 您应该将它们转换为一些中性的表示形式。

关于c++ - Visual C++ 中的预处理器工具 __COUNTER__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6947594/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com