【问题标题】:Can gcc inline an indirect function call through a constant array of function pointers?gcc 可以通过函数指针的常量数组内联间接函数调用吗?
【发布时间】: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:真正的代码使用了变量索引,我只是尽量减少显示的代码。
  • 对我来说,很明显你应该使用在编译时众所周知的常量索引,或者直接调用函数。否则,链接器将无法知道应该选择什么功能实现来扩展。也许宏连接(虽然是语义糖)?

标签: c gcc compiler-optimization indirection inline-functions


【解决方案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 不会内联常量函数表中的所有函数并自动生成一个开关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2016-06-14
  • 2019-04-21
  • 2011-06-19
  • 2012-01-04
相关资源
最近更新 更多