Будет ли "if ... ASSERT" удалено в сборке релиза? - PullRequest
3 голосов
/ 08 ноября 2011

Иногда я пишу код вроде

if (ptr)
    ASSERT(ptr->member);

вместо

ASSERT(!ptr || ptr->member);

потому что это более прямое ИМО. Сохранится ли избыточное сравнение в сборке выпуска?

Ответы [ 3 ]

6 голосов
/ 08 ноября 2011

Я бы сказал, что это зависит от вашего компилятора.

В режиме выпуска макрос ASSERT не оценивает ptr->member и преобразуется в тривиальное выражение, которое компилятор оптимизирует, но оператор if и соответствующее сравнение останутся без изменений.

Однако, если компилятор достаточно умен, чтобы определить, что условие не имеет побочных эффектов, он может оптимизировать весь оператор if. Компиляция в сборку (с использованием опции / FA ) даст вам определенный ответ.

2 голосов
/ 08 ноября 2011

Пока компилятор не тупой, да, он будет обрезан.

Попробуйте написать это в компиляторе:

if (x);

Это дает вам предупреждение, что утверждение не имеет никакого эффекта, и, как я уже сказал, если оно не глупо, оно удалит код.

Если вы хотите быть уверены, вы можете скомпилировать его с вашим компилятором и посмотреть сборку.

1 голос
/ 08 ноября 2011

LLVM удаляет его, когда требуется оптимизация (пользователем):

int main(int argc, char **argv) {
  if (argc) {}
  return 0;
}

становится:

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone {
  ret i32 0
}
...