Порядок условий в цикле while - PullRequest
6 голосов
/ 10 июля 2009

Прежде всего, прежде чем я начну, я использую VC ++ 2008 professional и использую Intel Core2 в ОС Windows. Я также знаю, что этот код НИКОГДА не будет выполняться на чем-либо кроме core2 / corei7 под управлением Windows.

У меня есть цикл while с двумя условиями, который выглядит примерно так: примечание: это очень упрощенная версия.

while((a != b) && (array[a] < c))

Если первое условие (a != b) генерирует ложное значение, будет ли оцениваться второе условие? или цикл просто прекратится прямо там?

Я провел несколько тестов, и кажется, что это действительно так.

Однако, здесь есть подвох. Когда и если первое условие оценивается как ложное, второе условие БУДЕТ генерировать нарушение доступа, если оно оценивается. Однако, как я вижу, после того, как первое условие оценивается как ложное, программа не удосуживается оценить второе условие и выходит из цикла, что спасает меня.

Проблема в том, что я не могу полностью избавиться от проблемы нарушения доступа, не заставив мой очень хороший и аккуратный код внезапно взорвать меня. Тем не менее, из-за небольшой «ошибки» (я знаю, что это оптимизация компилятора, а не ошибка), я, похоже, смог от нее избавиться. Я также знаю, что это, вероятно, не очень хорошая практика программирования, но, честно говоря, в моей ситуации, если это сработает, я уже впереди игры.

У меня вопрос: вернется ли этот «баг» или программная халатность и укусит ли меня когда-нибудь? Даже если учесть, что я проверил ад из этого раздела и ТОЛЬКО В ЭТОМ РАЗ БУДЕТ ИСПОЛЬЗОВАТЬСЯ ТОЛЬКО?

Ответы [ 6 ]

22 голосов
/ 10 июля 2009

Второе условие не будет оцениваться, пока первое не будет оценено как истинное. Вы можете рассчитывать на это. Миллионы строк кода работают, потому что именно так C и C ++ выполняют оценку логических выражений с коротким замыканием.

Вы можете использовать это и рассчитывать на это. Если первое выражение оценивается как ложное, второе даже не будет начинать вычислять.

4 голосов
/ 10 июля 2009

Это не ошибка. C ++ использует оценку короткого замыкания, поэтому второе условие никогда не будет оцениваться, если первое условие ложно.

2 голосов
/ 10 июля 2009

Это не будет оцениваться. Однако, если вы беспокоитесь о том, что подпрограмма, которую вы кодируете, вернется к вам, вы должны пересмотреть то, что пишете. Вы признали, что это плохая практика программирования. Вы уже знаете, это будет проблемой. Когда эти условия будут выполнены, просто исправьте это. Ты будешь ненавидеть себя меньше утром.

1 голос
/ 10 июля 2009

Второе условие не будет оцениваться, если первое условие не соответствует действительности. Как вы сказали, за этой оптимизацией следуют все компиляторы C ++.

Если вы все еще не можете это сделать, добавьте простое выражение if в это время.

while ( a != b ) {
    if ( array[a] < c )
    {
         // your code goes here.
    }
    else
    {
        break;
    }
}
1 голос
/ 10 июля 2009

Использование короткого замыкания логических операторов И и ИЛИ в С ++ не должно считаться плохой практикой. Он совершенно идиоматичен и часто приводит к более ясному и лаконичному коду.

* 1003 Е.Г. *

std::auto_ptr< SomeObject > data;

С коротким замыканием &&:

// Clear expired data, if present
if( data.get() && data->expired )
    data.reset();

Без использования короткого замыкания && вам потребуется дополнительный уровень if, что приведет к большему количеству подробного кода.

// Clear expired data, if present
if( data.get() )
{
    if ( data->expired )
        data.reset();
}
1 голос
/ 10 июля 2009

Язык гарантирует такое короткое замыкание, поэтому вам не следует беспокоиться об его использовании. Это также работает с || - если первое условие истинно, второе не оценивается.

...