彼が言っていること (私が思うに) は、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 のいずれかをインライン化する方法はありません。f1f2f1f2callThroughPointer
ただし、コンパイラがコンパイル時にどの関数が呼び出されるかを証明できる場合は、関数をインライン化することができます。例:
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…)