3

Let's say we have this code:

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

Can gcc be somehow tricked to really inline the indirect calls to func_*?

After compiling the code with -O2 and -O3, I could still spot a call func_2 instruction in the assembly output.

I know this hairy expression can be converted into a bulky switch statement with inlined calls for each case, but I prefer the former for its compactness.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • 1
    Judging from your code, it looks like you're *really* desperate to get this working, aren't you? :) – user541686 Feb 23 '11 at 22:19
  • Well, a bit of constant folding *should* allow inlining. But since it only works with constants anyway, why not call it directly? –  Feb 23 '11 at 22:21
  • @delnan: The real code uses a variable index, I just tried to minimize the code shown. – Blagovest Buyukliev Feb 23 '11 at 22:36
  • For me it's something obvious that you should use a constant index well known at compile time, or direct function call. Otherwise, linker will be unable to know what function implementation should be selected for expanding. Maybe macro concatenation (semantic sugar, though) ? – Martin Babacaev Feb 23 '11 at 22:43

1 Answers1

3

if it does not hurt you to allocate some space in the data segment, you can try like this:

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

my gcc 4.4.5 correctly inlines the function with -O2.

The aggregate initializer inside the code of the function does not forward the constant as we expect, I don't know wheter it's a gcc bug or our misunderstanding of some C rule.

Laurent G
  • 2,994
  • 1
  • 18
  • 10