FWIW poniższy kod
inline unsigned int f1(const unsigned int i, const bool b) {return b ? i : 0;}
inline unsigned int f2(const unsigned int i, const bool b) {return b*i;}
int main()
{
volatile unsigned int i = f1(42, true);
volatile unsigned int j = f2(42, true);
}
skompilowane z gcc -O2 produkuje ten montaż:
.file "test.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 2,,3
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movl $42, 8(%esp) // i
movl $42, 12(%esp) // j
xorl %eax, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE2:
nie ma wiele w lewo z obu f1
lub f2
, jak widać.
Jeśli chodzi o standard C++, kompilator może robić wszystko, co dotyczy optymalizacji, o ile nie zmienia obserwowalnego zachowania (reguła , tak jakby była).
Nie można wiedzieć, co "kompilator" zrobi z wyrażeniem (w przypadku argumentów znanych w czasie kompilacji) bez określenia, który kompilator, ale prawdopodobnie zoptymalizuje oba. Jeden ze sposobów opowiedzenia, skompiluj każdy ze znanych w czasie kompilacji argumentów i sprawdź wynik. –
Spójrz na wygenerowany kod zespołu – James
FWIW, MSVC generuje maskę i dodaje do pierwszego przypadku, a mnoży na sekundę, w przypadku, gdy uniemożliwiłem mu wykonanie sztuczek z oceną samego boolowskiego (jeśli to możliwe, zmieni test, który generuje bool w celu dalszej optymalizacji). Zasadniczo MSVC jest w obu przypadkach bez gałęzi i wydaje się bardziej optymalny w przypadku naiwnym. – JasonD