Имеются следующие две функции:
int f() { return 0; }
int g() { return 1; }
И следующий код для вызова одной из них в зависимости от логического значения b
:
int t0(bool b) { return (b ? &f : &g)(); }
int t1(bool b) { return b ? f() : g(); }
int t2(bool b) { return b ? t0(true) : t0(false); }
Оба g++ (trunk)
и clang++ (trunk)
с -std=c++2a -Ofast -march=native
не удалось оптимизировать следующий код:
int main(int ac, char**) { return t0(ac & 1); }
Создание следующей сборки:
main:
and edi, 1
mov eax, OFFSET FLAT:f()
mov edx, OFFSET FLAT:g()
cmove rax, rdx
jmp rax
Вызов t1
или t2
(вместо t0
) производит следующую оптимизированную сборку:
main:
mov eax, edi
not eax
and eax, 1
ret
Все может быть воспроизведено live на gcc.godbolt.org .
Я нахожу загадочным, что вызов t0
непосредственно в main
не оптимизируется, в то время как вызов в t2
в порядке.
Есть ли причина, по которой при вызове t0
не получается такая же сборка, как у t1
или t2
? Или это упущенная возможность оптимизации как для g++ (trunk)
, так и clang++ (trunk)