2011-01-24 3 views
5

Я читал во многих местах, но я действительно не могу понять указанное поведение в условных выражениях.Оператор связи в условном

Я понимаю, что в присваиваниях он вычисляет первый операнд, отбрасывает результат, затем вычисляет второй операнд.

Но для этого кода, что он должен был делать?

CPartFile* partfile = (CPartFile*)lParam; 
ASSERT(partfile != NULL); 
bool bDeleted = false; 
if (partfile,bDeleted) 
    partfile->PerformFileCompleteEnd(wParam); 

Файл partfile в IF был ненужным аргументом или имел какой-либо смысл?

+0

Возможно, это поможет: http://stackoverflow.com/questions/54142/c-comma-operator –

+0

Одной из возможностей является что кодер имел в виду 'if (partfile && bDeleted)', некоторые другие языки программирования имеют 'IF a, b' для обозначения« if a и b » –

ответ

9

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

+3

Оператор запятой является переопределяемым. Возможно, использование этого может изменить состояние левого выражения. – Benoit

+0

@Benoit Он не может быть перегружен для двух примитивных типов (указатель и bool в этом случае); по крайней мере один операнд должен иметь тип класса –

4

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

partfile,bDeleted Так бы evaulate любой partfile бы, отбросить этот результат, затем вычислить и вернуть bDeleted

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

Для получения дополнительной информации см Wikipedia: Comma operator

+0

Оператор запятой не оценивает элементы n-1. Каждый оператор в C/C++ является либо унарным, либо двоичным. Если вы поместите несколько операторов запятой в одну строку, он будет оценивать первый элемент, отбрасывать его, оценивать второй элемент и использовать второй элемент в качестве операнда для следующего оператора запятой в строке. Конечно, результат будет таким же, как если бы он оценил n-1 элементов, но чтобы понять, почему, вам нужно знать, что происходит между ними, чтобы добраться до последнего элемента. – Lundin

+0

Хороший момент, я думал, что a, b, c был одним термином (это правильная формулировка?), Но это не так, потому что там есть два оператора запятой. фиксированное сообщение – helloworld922

1

PartFile оценивается, то bDeleted вычисляется и используется в качестве теста. Поскольку оценка partfile не имеет каких-либо побочных эффектов, удаление его из условного значения не имеет эффекта.

+0

У вас есть это в обратном направлении, partfile получает оценку и игнорируется, а bDeleted оценивается и возвращается. – helloworld922

+0

@ helloworld922: так верно, исправится. – ThomasMcLeod

2
bool bDeleted = false; 
if (partfile,bDeleted) 
    partfile->PerformFileCompleteEnd(wParam); 

Здесь if оператор оценивает PartFile, bDeleted, но bDelete всегда ложно, поэтому выражение не запускается. Ключевой вопрос: «Что это такое?». Вероятным ответом является то, что кто-то временно хотел предотвратить выполнение оператором partfile->PerformFileCompleteEnd(wParam);, возможно, потому, что он вызывал некоторые проблемы, или они хотели, чтобы более поздний код сообщал о ошибках должным образом, если этот шаг не был выполнен. Чтобы они помнили, как использовался код, они оставили старую логику «if (partfile)», но добавили жестко закодированную переменную bDeleted для документирования того, что логика partfile->Perform... была «удалена» из программы.

Лучший способ временно отключить такой код, вероятно ...

#if 0 
    if (partfile) 
     partfile->PerformFileCompleteEnd(wParam); 
#endif 

... хотя иногда я стараюсь документировать рассуждения тоже ...

#ifndef DONT_BYPASS_FILE_COMPLETE_PROCESSING_DURING_DEBUGGING 
    if (partfile) 
     partfile->PerformFileCompleteEnd(wParam); 
#endif 

... или ...

if (partFile, !"FIXME remove this after debugging") 
    partfile->PerformFileCompleteEnd(wParam); 

лучший выбор зависит от вашего набора инструментов и существующих привычек (например, некоторые редакторы выделения «FIXME» и «TODO» в обратном видео, поэтому трудно пропустить или серое из #if 0 блоков; у вас могут быть определенные строки, о которых предупреждает ваш контрольный элемент управления версиями; препроцессор определяет только в версиях debug vs release, которые могут предотвратить случайное распространение и т. д.).

1

Оператор запятой - довольно скрытая особенность C/C++. Его не следует путать с запятой в инициализирующих списках (т. Е. Int x, int y;), ни с запятой разделения параметров вызова функции (т.е.: func (x, y)).

Оператор запятой имеет одну цель: предоставить программисту гарантированный порядок оценки выражения. Для почти каждого оператора в C/C++ порядок оценки выражений не определен. Если я напишу

result = x + y;

где x и y являются подвыражениями, то сначала можно оценить либо x, либо y. Я не знаю, что, это зависит от компилятора. Если вы, однако, пишите

result = x, y;

порядок оценки гарантированно стандартным: левый сперва.

Разумеется, использование этого в реальных приложениях весьма ограничены ...

Смежные вопросы