2010-07-13 50 views
1

我有一个运行在嵌入式系统上的代码,它必须运行得非常快。我知道C和宏,这个特定的项目主要用C语言编写,但它也使用C++模板[越来越多]。有一个内联函数:使用C++模板或宏进行编译时函数生成

inline my_t read_memory(uint32 addr) { 
    #if (CURRENT_STATE & OPTIMIZE_BITMAP) 
    return readOptimized(addr); 
    #else 
    return MEMORY[addr]; 
    #endif 
} 

此功能从以优化的方式存储或基于当前状态的传统方式,并告诉是否在特定状态或不使用优化的位图的读取。

#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 

和执行过程中(好吧,编译)时,我试图重新定义CURRENT_STATE像这样:

int main(){ 
    #define CURRENT_STATE STATE_A 
    do_a(); 
    #undef CURRENT_STATE 
    #define CURRENT_STATE STATE_B 
    do_b(); 
    .... 
} 

所有do_X()函数使read_memory()调用。我无法使这种方法奏效。当我使用#warning语句时,当前状态的值始终为STATE_A。这不是我的问题,但如果你能帮助我,我会倍感高兴。所以,我的问题是,有没有办法使用模板而不是宏来做这种事情?

更多信息:我必须使用内联函数,因为我无法导出MEMORY [],这是一个库函数。我真的不喜欢修改函数原型(如read_memory()...),但它会做。另外,请原谅我的默默无闻。

千恩万谢,

+1

为什么你想使用模板来做到这一点? – 2010-07-13 20:09:35

+0

这就是我可以想到的编译时决策,因为我不想在运行时决定。但我很开放。 – perreal 2010-07-13 20:17:05

+1

好的,是什么让你认为运行时决策太慢?你有没有介绍过这样的事情?我们都希望我们的代码运行“非常快”,99.99%的时间正是它所做的,而无需使用宏或模板。 – 2010-07-13 20:26:04

回答

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); 
    .... 
} 

编译器将会认识到state & OPTIMIZE_BITMAP是一个常量,并为每个模板实例优化出if的一个或其他分支。

+2

+1,肯定比专精更清晰:) – 2010-07-13 20:40:29

+0

由于'state'和'OPTIMIZE_BITMAP'是常量,所以编译器很可能会完全消除测试和死代码,从而达到相同的效果。 – 2010-07-14 06:42:37

5

我想你可能误会什么编译器(或者更确切地说,预处理器)不与#define语句。

您的示例(以下引用)没有用,因为CURRENT_STATE未在#define和#undef之间使用。预处理器不是“执行”你的代码,或者是在这里扩展do_a()。 #defines和宏扩展只能发生在你的源代码行中。

#define CURRENT_STATE STATE_A 
    do_a(); 
    #undef CURRENT_STATE 

这是基于预处理器的解决方案,如果模板让你感到恐惧。我们假设do_a()应该使用优化版本。现在

inline my_t read_memory(uint32 addr) 
{ 
    return MEMORY[addr]; 
} 

inline my_t read_memory_optimized(uint32 addr) 
{ 
    return readOptimized(addr); 
} 

,创建DO_CONFIG.H

#if defined(DO_A) || (defined(DO_C) || ...) 
    #define READ_MEMORY read_memory_optimized 
#else 
    #define READ_MEMORY read_memory 

DO_A.C,在顶部

#define DO_A 
#include DO_CONFIG.H 

添加此...,并使用x=READ_MEMORY(addr)代替x=read_memory(addr)。要优化非优化切换,只需改变DO_CONFIG.H

+0

我很蠢,谢谢 – perreal 2010-07-13 20:36:45

+1

@perreal。你在这里问问题。这很聪明! – Roddy 2010-07-13 20:47:51

+0

所以,可能类似于 #define CURRENT_STATE STATE_A #include“usr_do_a.c” do_a(); #undef CURRENT_STATE ... 会工作吗?很多文件... – perreal 2010-07-13 21:04:00