Я прочитал код устаревшего кода:
if ( 1 || !Foo() )
Есть ли причина, почему бы не написать:
if ( !Foo() )
Я прочитал код устаревшего кода:
if ( 1 || !Foo() )
Есть ли причина, почему бы не написать:
if ( !Foo() )
Два из них не одинаковы. Первый никогда не будет оценивать Foo()
, потому что 1
замыкает ||
.
Почему это произошло - возможно, кто-то хотел принудительно ввести запись в ветку then
для целей отладки и оставил ее там. Также может быть, что это было написано до контроля источника, поэтому они не хотели, чтобы код был потерян, а теперь просто обошел.
if (1 || !Foo() )
всегда будет выполняться. !Foo()
даже не будет достигнуто из-за оценка коротких замыканий.
Это происходит, когда вы хотите убедиться, что код под if
будет выполнен, но вы не хотите удалять в нем реальные условия, возможно, для целей отладки.
Дополнительная информация, которая может вам помочь:
if(a && b)
- если a
false
, b
не будет проверяться.if(a && b)
- если a
- true
, будет проверен b
, потому что если он false
, выражение будет false
.if(a || b)
- если a
равно true
, b
не будет проверяться, потому что это true
в любом случае.if(a || b)
- если a
- false
, будет проверен b
, потому что если b
есть true
, то это будет true
.Настоятельно рекомендуется иметь макрос для этой цели, скажем DEBUG_ON 1
, что упростит понимание того, что означает программист, и не иметь магических чисел в коде (спасибо @grigeshchauhan).
1 || condition
всегда истинно, независимо от того, является ли значение condition
истинным или нет. В этом случае condition
никогда не оценивается. Следующий код:
int c = 5;
if (1 || c++){}
printf("%d", c);
выводит 5
, так как c
никогда не увеличивается, однако если вы изменили 1
на 0
, на самом деле вызывается c++
, делая вывод 6
.
Обычное практическое использование этого - в ситуации, когда вы хотите протестировать часть кода, которая вызывается, когда выполняется условие, которое оценивается только true:
if (1 || condition ) {
// code I want to test
}
Этот способ condition
никогда не будет оценен, и поэтому // code I want to test
всегда вызывается. Однако это определенно не то же самое, что:
if (condition) { ...
который является инструкцией, где condition
будет фактически оценен (и в вашем случае будет вызываться Foo
)
На вопрос ответили правильно - разница заключается в том, что правая часть операции или коротко замкнута, что означает, что это код отладки для принудительного ввода в блок if.
Но в интересах лучших практик, по крайней мере, мой грубый удар в лучшем случае, я бы предложил альтернативы в порядке возрастания предпочтений (последнее самое лучшее):
note: заметили, что после кодированных примеров это был вопрос С++, примерами являются С#. Надеюсь, вы сможете перевести. Если кто-то нуждается в меня, просто отправьте комментарий.
Комментарий в строке:
if (1 /*condition*/) //temporary debug
Комментарий вне линии:
//if(condition)
if(true) //temporary debug
Имя-индикативная функция
//in some general-use container
bool ForceConditionForDebug(bool forcedResult, string IgnoredResult)
{
#if DEBUG
Debug.WriteLine(
string.Format(
"Conditional {0} forced to {1} for debug purposes",
IgnoredResult,
forcedResult));
return forcedResult;
#else
#if ALLOW_DEBUG_CODE_IN_RELEASE
return forcedResult;
#else
throw new ApplicationException("Debug code detected in release mode");
#endif
#endif
}
//Where used
if(ForceConditionForDebug(true, "condition"))...
//Our case
if(ForceConditionForDebug(true, "!Foo()"))...
И если вы хотите действительно надежное решение, вы можете добавить правило репозитория для управления исходным кодом, чтобы отклонить любые проверенные в коде, которые называются ForceConditionForDebug. Этот код никогда не должен был быть написан таким образом, потому что он явно не передает намерения. Он никогда не должен был проверяться (или был разрешен для проверки) (проверка контроля над версиями?) И его, безусловно, никогда не разрешать выполнять в производстве в его текущей форме.