2016-02-18 5 views
1

Можно ли оценивать условное утверждение даже при условии, что внутри блока условных операторов нет допустимого оператора? Если да, то как оптимизировать код для того, чтобы не оценивать условное утверждение в этом случае? Для экс:C-условный оператор C, связанный с оптимизацией

if(get_value() !=NULL) 
{ 
} 

или

if(get_value() != NULL) 
{ 
do{}while(0); 
} 

В нескольких местах, в существующем проекте, просто чтобы получить отладочные отпечатки, есть проверки, как это. Печать может быть сведена с помощью макрофункции, но как оптимизировать условные операторы? Это очень трудно удалить эти сравнения вручную

+0

Это будет зависеть от оптимизации компилятора. Некоторые компиляторы будут проверять условия, которые не оказывают никакого эффекта и удаляют его. – niyasc

+0

Зачем вам этот код? Вы можете просто выполнить 'if (! Get_value()) и сделать там _important stuff_. – ForceBru

+0

Зависит от компилятора и оптимизатора ...Некоторые оптимизаторы кода UC могут даже скомпилировать более длинный код в файл меньшего размера, потому что более длинный код будет соответствовать (на уровне сборки) с другой подпрограммой где-нибудь, а более короткий - нет. Но в целом, это не принесет пользы ... – Ian

ответ

0

Стандарты C и C++ требуют, чтобы компилятор для того, чтобы get_value() оценивается (или, по крайней мере, вести себя как если бы это были оценены).

Так что в общем случае будет оцениваться get_value. Вы можете легко проверить это with godbolt:

extern int* get_value(); 

int func() { 
    if(get_value() !=NULL) 
    { 
    } 
} 

Производит сборку x86 на GCC 4.4.7 следующим образом:

sub  rsp, 8 
    call get_value() 
    add  rsp, 8 
    ret 

Обратите внимание, что get_value() называется, но = NULL проверка не бывает так! что сравнение не наблюдается. Поэтому для этого компилятора вы можете сказать, что строгое мнение о том, что полное сравнение не оценивается, но сравнение не полностью устранено, так как get_value все равно должен быть вызван (что, вероятно, является дорогостоящей частью).

Компилятор вынужден пройти этот путь, поскольку не знает, какие побочные эффекты могут иметь get_value, поэтому он должен назвать это. Можно игнорировать возвращаемое значение, так как он знает, что сравнение и пустое тело if-statement не имеют никакого эффекта.

В одном конкретном случае, однако, компилятор мог исключить весь оператор - если он может доказать во время компиляции, что метод не имеет побочного эффекта. Это возможно, если метод get_value объявлен в той же единице компиляции (и, возможно, также с некоторой оптимизацией времени привязки).

Мы обновляем пример поставить реализацию get_value внутри модуля компиляции, и убедитесь, что он не имеет побочных эффектов:

int* get_value() { 
    return 0; 
} 

int func() { 
    if(get_value() !=NULL) 
    { 
    } 
} 

Теперь, метод compiled into a no-op:

func(): 
     rep 
     ret 

(для функция этого бесполезного префикса префектуры, see here ...)

Так что все зависит от деталей get_value, и насколько компилятор может знать об этом, когда компилирует ваш пустой оператор if.