【发布时间】:2018-06-29 15:49:32
【问题描述】:
是否可以在我的代码中定义执行不同代码路径的部分或范围,不使用全局或传递状态变量?
出于调试目的,我希望能够用范围或#define 包围一段错误代码,以临时打开此部分中的预定义调试行为,例如使用调试数据、更精确的数据类型、已验证的算法……这需要在多线程应用程序中工作,其中多个线程可能会同时执行相同的共享代码,但只有其中一些线程从内部调用了此代码定义的部分。
例如,这里有一些伪代码不起作用,但可以说明我想要做什么。从多个地方同时调用的静态昂贵函数:
Result Algorithms::foo()
{
#ifdef DEBUG_SECTION
return Algorithms::algorithmPrecise(dataPrecise);
#else
return Algorithms::algorithmOptimized(dataOptimized);
#endif
}
其中实例需要经常更新的三个类:
Result A::update()
{
return Algorithms::foo();
}
Result B::update()
{
Result result;
#define DEBUG_SECTION
...
result = a.update() + 1337;
...
#undef DEBUG_SECTION
return result;
}
Result C::update()
{
return a.update();
}
如你所见,A 类直接调用foo(),而在B 类中,foo() 是通过调用a.update() 和其他一些东西间接调用的。让我们假设B::update() 返回一个错误的结果,所以我希望能够仅从这个位置使用foo() 的调试实现。在C::update(),还是应该使用优化后的版本。
我的概念性想法是在错误代码周围定义一个DEBUG_SECTION,它将在此位置使用调试实现。然而,这在实践中是行不通的,因为Algorithms::foo() 被编译一次,而DEBUG_SECTION 没有被定义。在我的应用程序中,Algorithms、A、B 和 C 位于不同的库中。
我希望在代码中定义的部分中,执行共享代码中的不同代码部分。但是,在本节之外,我仍然希望执行原始代码,这将在运行时同时发生,因此我不能简单地使用状态变量。我可以在DEBUG_SECTION 中的每个调用中添加一个debugFlag 参数,该参数在每个递归调用中向下传递,然后提供给Algorithms::foo(),但这极容易出错(你不能错过任何调用,但是部分可能非常大,分布在不同的文件中,......)并且在更大的系统中非常混乱。有没有更好的方法来做到这一点?
我需要 C++11 和 MSVC 的解决方案。
【问题讨论】:
-
#if不能依赖于运行时动态发生的任何事情,它在编译时由预处理器处理。 -
听起来你应该使用线程局部变量。
-
我理解为什么这个例子不能工作。但我在编译时已经知道“部分”,我认为可能有一种方法可以将这一点告诉编译器。
标签: c++ c++11 visual-c++