gcc 可以通过函数指针的常量数组内联间接函数调用吗?

Posted

技术标签:

【中文标题】gcc 可以通过函数指针的常量数组内联间接函数调用吗?【英文标题】:Can gcc inline an indirect function call through a constant array of function pointers? 【发布时间】:2011-07-03 03:29:45 【问题描述】:

假设我们有这个代码:

inline int func_2 (int a, int b) 
  return time() + a * b;


int main (void) 
  int x = (int (*[])(int, int))func_1, func_2, func_3[1](6, 7);

gcc 是否可以被欺骗以真正内联对func_* 的间接调用?

使用-O2-O3 编译代码后,我仍然可以在汇编输出中发现call func_2 指令。

我知道这个毛茸茸的表达式可以转换成一个庞大的 switch 语句,每个 case 都有内联调用,但我更喜欢前者,因为它紧凑。

【问题讨论】:

从您的代码来看,您似乎真的不顾一切地想要让它工作,不是吗? :) 嗯,一点恒定折叠应该允许内联。但是既然它无论如何只适用于常量,为什么不直接调用它呢? @delnan:真正的代码使用了变量索引,我只是尽量减少显示的代码。 对我来说,很明显你应该使用在编译时众所周知的常量索引,或者直接调用函数。否则,链接器将无法知道应该选择什么功能实现来扩展。也许宏连接(虽然是语义糖)? 【参考方案1】:

如果在数据段中分配一些空间不会对您造成伤害,您可以这样尝试:

static int func_2 (int a, int b) 
    return time() + a * b;


static int (* const ftab[])(int,int) = func_1, func_2, func_3;

int foo (void) 
    return ftab[1](6,7);

我的 gcc 4.4.5 使用 -O2 正确内联函数。

函数代码里面的聚合初始化并没有像我们预期的那样转发常量,不知道是gcc的bug还是我们对某些C规则的误解。

【讨论】:

来自 cmets,索引应该是 variable 而不是 constant 当然,在这种情况下,答案是否定的,GCC 不会内联常量函数表中的所有函数并自动生成一个开关。

以上是关于gcc 可以通过函数指针的常量数组内联间接函数调用吗?的主要内容,如果未能解决你的问题,请参考以下文章

直接调用间接调用和内联调用

C 语言一级指针 易犯错误 模型 ( 判定指针合法性 | 数组越界 | 不断修改指针变量值 | 函数中将栈内存数组返回 | 函数间接赋值形参操作 | 指针取值与自增操作 )

C 语言指针间接赋值 ( 指针作为 函数参数 的意义 | 间接赋值 代码示例 )

C基础指针的使用

使用内联汇编器从 GCC 中的共享库调用函数

GCC内联汇编中的C数组?