Вопрос теоретикам C++
{
if ( /*уcловие*/ )
{
// какие-то действия
}
}
или
{
if ( ! /*уcловие*/ ) return;
// какие-то действия
}
И первая и другая конструкция работает с одинаковой скоростью.
Ты смеешься?
И первая и другая конструкция работает с одинаковой скоростью.
Не смеюсь, соверешенное серьезно.
С одинаковой скоростью это предположение?
Например, обе конструкции имеют одну проверку условия, но вторая содержит две точки выхода из функции - одна по условию, а вторая в конце, как и у первой.
Например, обе конструкции имеют одну проверку условия, но вторая содержит две точки выхода из функции - одна по условию, а вторая в конце, как и у первой.
Твой вопрос не относится к языку программирования.
Это вопрос реализации компилятора и оптимизатора.
В общем случае можно считать, что приведенные примеры равнозначны.
Кроме того, я бы рекомендовал не заострять своё внимание на таких пустяках. Есть куда более (на порядки) более критичные места в любом коде.
К примеру, i++ и ++i.
Для оптимизации кода надо сначала делать его профилирование.
Нифига она не имеет две точки выхода на деле.
Всё зависит от реализации компилятора.
Нифига она не имеет две точки выхода на деле.
Когда приводишь подобное высказывание, ты хоть поясняй откуда это следует. Ты говоришь - не имеет, я говорю - имеет и кто круче :)
К примеру, i++ и ++i
Как ни странно, эту разницу я знаю и использую :D
Всё зависит от реализации компилятора
Допустим Builder
А слышали о brainfucker'е?
Это у тебя такой компилятор? :D
ОК. Именно. А какой компилятор будет формировать две точки выхода?
Например компилятор из Visual Studio при включенной оптимизации.
Ну, как сказал Green, все зависит от компилятора. Хотелось бы узнать каким будет код с двумя точками выхода. Если не сложно, приведите.
Да нет. Представь себе, есть такой язык (или его подобие), состоящий всего из 8-и команд. Просто интересно и все.
Ну, как сказал Green, все зависит от компилятора. Хотелось бы узнать каким будет код с двумя точками выхода. Если не сложно, приведите.
Да пожалуйста:
int j=0;
void func()
{
if (i == 0)
{
i = j;
return;
}
i = -1;
return;
}
Дизассм:
{
if (i == 0)
00401050 mov eax,dword ptr ds:[00409620h]
00401055 test eax,eax
00401057 jne 00401064
{
i = j;
00401059 mov eax,dword ptr ds:[00409624h]
0040105E mov dword ptr ds:[00409620h],eax
return;
}
00401063 ret
return;
}
i = -1;
00401064 mov dword ptr ds:[00409620h],0FFFFFFFFh
return;
}
0040106E ret
1.
{
if ( /*уcловие*/ )
{
// какие-то действия
}
}
cmp ...,...
retne
...какие-то действия
2.
{
if ( ! /*уcловие*/ ) return;
// какие-то действия
}
То же самое. А если код функции содержит какие-либо завершающие действия?
Допустим Builder
Вот, к примеру, C++Bulder 3:
{
a=b;
}
cmp eax,dword ptr [_b]
jle short @7
mov edx,dword ptr [_b]
mov dword ptr [_a],edx
@7:
a=b;
cmp eax,dword ptr [_b]
jle short @7
mov edx,dword ptr [_b]
mov dword ptr [_a],edx
@7:
Тут проявляется специфика построения кода функции. Вместо jle можно поставить retle, но переход необходим из-за завершающего кода. Этот пример вовсе не представляет типичную реализацию. Все зависит от компилятора и кода.
Да пожалуйста:
int j=0;
void func()
{
if (i == 0)
{
i = j;
return;
}
i = -1;
return;
}
Дизассм:
{
if (i == 0)
00401050 mov eax,dword ptr ds:[00409620h]
00401055 test eax,eax
00401057 jne 00401064
{
i = j;
00401059 mov eax,dword ptr ds:[00409624h]
0040105E mov dword ptr ds:[00409620h],eax
return;
}
00401063 ret
return;
}
i = -1;
00401064 mov dword ptr ds:[00409620h],0FFFFFFFFh
return;
}
0040106E ret
Не совсем это я имел в виду. В общем, не важно уже.