彼が言っていること (私が思うに) は、add
関数がインライン化されていないということです。言い換えれば、コンパイラは次のdo_op
ようにインライン化する可能性があります。
int c = func_ptr(4, 5);
add
ただし、次のようにインライン化することもありません。
int c = 4 + 5;
しかし、その単純な例では彼は間違っているかもしれません。
一般に、ポインターを介して関数を呼び出す場合、コンパイラーは (コンパイル時に) 呼び出す関数を認識できないため、関数をインライン化できません。例:
void f1() { ... }
void f2() { ... }
void callThroughPointer() {
int i = arc4random_uniform(2);
void (*f)() = i ? f2 : f1;
f();
}
ここで、コンパイラは or を呼び出すかどうかを知ることができないためcallThroughPointer
、 or のいずれかをインライン化する方法はありません。f1
f2
f1
f2
callThroughPointer
ただし、コンパイラがコンパイル時にどの関数が呼び出されるかを証明できる場合は、関数をインライン化することができます。例:
void f1() { ... }
void f2() { ... }
void callThroughPointer2() {
int i = arc4random_uniform(2);
void (*f)() = i ? f2 : f1;
f = f1;
f();
}
f
ここで、コンパイラはが常に であることを証明できるため、f1
にインラインf1
化できcallThroughPointer2
ます。(インライン化するとは限りませんf1
…)
同様に、投稿で引用した例では、コンパイラfunc_ptr
は が常にadd
の呼び出しにあることを証明できるためdo_op
、 inline が許可されていますadd
。(インライン化するとは限りませんadd
…)