Jos*_*hua 17 c embedded function
我知道至少有三种流行的方法可以使用多个名称来调用相同的函数.我实际上没有听说有人为此目的使用第四种方法.
1).可以使用#defines:
int my_function (int);
#define my_func my_function
Run Code Online (Sandbox Code Playgroud)
要么
#define my_func(int (a)) my_function(int (a))
Run Code Online (Sandbox Code Playgroud)
2).嵌入式函数调用是另一种可能性
int my_func(int a) {
return my_function(a);
}
Run Code Online (Sandbox Code Playgroud)
3).在链接器中使用弱别名:
int my_func(int a) __attribute__((weak, alias("my_function")));
Run Code Online (Sandbox Code Playgroud)
4).功能指针:
int (* const my_func)(int) = my_function;
Run Code Online (Sandbox Code Playgroud)
我需要多个名称的原因是数学库具有相同方法的多个实现.
例如,我需要一种有效的方法来计算标量浮点数的平方根.所以我可以使用math.h的sqrt().这不是很有效.所以我写了一两个其他方法,比如使用牛顿方法.问题是每种技术在某些处理器上更好(在我的情况下是微控制器).所以我希望编译过程选择最好的方法.
我认为这意味着最好使用宏或弱别名,因为这些技术可以很容易地在头文件中的几个#ifdef语句中进行分组.这简化了维护(相对).也可以使用函数指针,但它必须在源文件中,头文件中的常规函数的extern声明.
您认为哪种方法更好?
编辑:
从提议的解决方案中,似乎有两个重要问题我没有提到.
问:用户主要使用C/C++吗?
答:所有已知的开发都将采用C/C++或汇编语言.我正在设计这个库供我个人使用,主要用于裸机项目.将没有或最小的操作系统功能.在完整的操作系统中使用它的可能性很小,这需要考虑语言绑定.由于这是为了个人成长,因此在流行的嵌入式操作系统上学习库开发将是有利的.
问:用户是否需要/想要一个暴露的库?
答:到目前为止,是的.由于它只是我,我想对测试后使用的每个处理器进行直接修改.这是测试套件有用的地方.所以一个暴露的图书馆会有所帮助.另外,特定功能的每个"最佳实现"可能具有失败的条件.此时,必须决定谁解决问题:用户或图书馆设计师.用户需要一个公开的库来解决失败的情况.我既是"用户"又是"图书馆设计师".两者都允许几乎更好.然后非实时应用程序可以让库解决所有稳定性问题,但是实时应用程序可以考虑算法速度/空间与算法稳定性.
根据您图书馆的目标受众,我建议您选择两种方案:
如果您的库的使用者保证是Cish,请使用#define sqrt newton_sqrt以获得最佳可读性
如果您的库的某些消费者不属于C类(想想绑定到Dephi,.NET,等等),请尽量避免消费者可见#defines.这是绑定的主要PITA,因为宏在二进制文件上不可见 - 嵌入式函数调用是最具绑定性的.
你能做的就是这个。在头文件 (.h) 中:
int function(void);
Run Code Online (Sandbox Code Playgroud)
在源文件 (.c) 中:
static int function_implementation_a(void);
static int function_implementation_b(void);
static int function_implementation_c(void);
#if ARCH == ARCH_A
int function(void)
{
return function_implementation_a();
}
#elif ARCH == ARCH_B
int function(void)
{
return function_implementation_b();
}
#else
int function(void)
{
return function_implementation_c();
}
#endif // ARCH
Run Code Online (Sandbox Code Playgroud)
调用一次的静态函数通常由实现内联。例如,gcc默认情况下 : -finline-functions-called-once是这种情况,即使在-O0. 未调用的静态函数通常也不包含在最终二进制文件中。
请注意,我没有将#ifand#else放在单个function主体中,因为当#if指令位于函数主体之外时,我发现代码更具可读性。
请注意,这种方式更适用于嵌入式代码,其中库通常以其源代码形式分发。
| 归档时间: |
|
| 查看次数: |
3614 次 |
| 最近记录: |