Ответ 1
То, что он говорит (я думаю), заключается в том, что функция add
не входит в состав. Другими словами, компилятор может встроить do_op
следующим образом:
int c = func_ptr(4, 5);
но он не будет также inline add
следующим образом:
int c = 4 + 5;
Однако он может ошибаться в этом простом примере.
Как правило, когда вы вызываете функцию через указатель, компилятор не может знать (во время компиляции), какую функцию вы будете вызывать, поэтому он не может встроить функцию. Пример:
void f1() { ... }
void f2() { ... }
void callThroughPointer() {
int i = arc4random_uniform(2);
void (*f)() = i ? f2 : f1;
f();
}
Здесь компилятор не может знать, будет ли callThroughPointer
вызывать 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
. (Это не значит, что он будет inline f1
...)
Аналогично, в примере, который вы цитировали в своем сообщении, компилятор может доказать, что func_ptr
всегда add
в вызове do_op
, поэтому ему разрешено встроить add
. (Это не значит, что он будет inline add
...)