per*_*eal 1 c++ macros templates cuda inline
我有一个在嵌入式系统上运行的代码,它必须运行得非常快.我知道C和宏,这个特定的项目主要用C编码,但它也使用C++模板[越来越多].有一个内联函数:
inline my_t read_memory(uint32 addr) {
#if (CURRENT_STATE & OPTIMIZE_BITMAP)
return readOptimized(addr);
#else
return MEMORY[addr];
#endif
}
Run Code Online (Sandbox Code Playgroud)
该函数以优化的方式或基于当前状态的传统方式从存储器读取,并且位图告知是否在特定状态下使用优化.
#define STATE_A 0x0001
#define STATE_B 0x0010
#define STATE_C 0x0100
#define STATE_D 0x1000
#define OPTIMIZE_BITMAP 0x1010 // optimize states d and b
Run Code Online (Sandbox Code Playgroud)
在执行过程中(好的,编译),我尝试重新定义CURRENT_STATE,如下所示:
int main(){
#define CURRENT_STATE STATE_A
do_a();
#undef CURRENT_STATE
#define CURRENT_STATE STATE_B
do_b();
....
}
Run Code Online (Sandbox Code Playgroud)
所有do_X()函数都会调用read_memory().我无法使这种方法奏效.当我使用#warning语句时,我可以看到当前状态的值总是STATE_A.这不是我的问题,虽然如果你可以帮助我,我会很高兴.所以,我的问题是,有没有办法使用模板而不是宏来做这种事情?
更多信息:我必须使用内联函数,因为我无法导出MEMORY [],这是一个库函数.我真的不想修改函数原型(比如read_memory()...)但它会这样做.另外,原谅我的默默无闻.
非常感谢,
Ant*_*ams 10
内联函数将在声明它的转换单元中解析一次,并且将使用该点处的宏的状态.使用不同定义的宏多次调用该函数不会更改函数的定义.
您可以使用模板执行此操作---如果您将"当前状态"作为模板参数传递,则可以在每个调用点使用不同的实例化:
template<unsigned state>
inline my_t read_memory(uint32 addr) {
if(state & OPTIMIZE_BITMAP)
return readOptimized(addr);
else
return MEMORY[addr];
}
int main(){
read_memory<STATE_A>(some_addr);
read_memory<STATE_B>(some_addr);
....
}
Run Code Online (Sandbox Code Playgroud)
编译器将意识到这state & OPTIMIZE_BITMAP是一个常量并优化if每个模板实例化的一个或其他分支.
我想你可能误解了编译器(或者更确切地说,预处理器)对#defines的作用.
您的示例(下面引用)没有用,因为#define和#undef之间没有使用CURRENT_STATE.预处理器没有"执行"您的代码,或者此时内联扩展do_a().#defines和宏扩展只能在你的来源的线路中完全出现.
#define CURRENT_STATE STATE_A
do_a();
#undef CURRENT_STATE
Run Code Online (Sandbox Code Playgroud)
这是一个基于预处理器的解决方案,如果模板让你感到恐惧.我们假设do_a()应该使用优化版本.
inline my_t read_memory(uint32 addr)
{
return MEMORY[addr];
}
inline my_t read_memory_optimized(uint32 addr)
{
return readOptimized(addr);
}
Run Code Online (Sandbox Code Playgroud)
现在,创造 DO_CONFIG.H
#if defined(DO_A) || (defined(DO_C) || ...)
#define READ_MEMORY read_memory_optimized
#else
#define READ_MEMORY read_memory
Run Code Online (Sandbox Code Playgroud)
在DO_A.C,顶部添加此项
#define DO_A
#include DO_CONFIG.H
Run Code Online (Sandbox Code Playgroud)
......而x=READ_MEMORY(addr)不是使用x=read_memory(addr).要从优化切换到非优化,只需更改DO_CONFIG.H