2010-10-03 3 views
9
void main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;//is this fine? 
} 

В последнее время я начал читать информацию о точках последовательности, но я не могу понять, является ли вышеуказанный образец кода точным или нет. Я знаю, что оператор && вводит точку последовательности, поэтому я не очень уверен в поведении выражения z = x & & y & & ++ z. Кто-нибудь, пожалуйста, скажите мне правильный ответ.сложное выражение, включающее логическое И (&&)

+4

возвращаемый тип 'главного()' должен быть 'int' в C и в C++. –

ответ

-2

Да, это скомпилирует.

Но если вы спрашиваете о логических ошибках:

1) оператор && вводит точку последовательности, поскольку она может прекратить вычисление выражения, когда он знает наверняка конечный результат (в данном случае значения 0 может прекратить оценку), поэтому он даже не достигнет части ++z, если x или y равно нулю.

2) потому что оператор && является логическим, результат всегда будет 0 или 1, и я сомневаюсь, что это то, что вы хотели.

6

В C++ 03.

void main(void) 
{ 
    int x,y,z; 
    x=y=z=1;         // Seq1 at ; 

    z = x && y && ++z;//is this fine?   // Seq2 at ; 
} 

NB: Обратите внимание, что есть точки последовательности у оператора & & но те не имеют значения в данном примере.

Отлично !. В общем, может быть или нет. Зависит от значений x и y. В вашем конкретном случае это не нормально. Этот код может иметь что-то, называемое undefined behavior.

Если г ++ оценивается (как в вашем примере, потому что х и у 1), то скалярная переменная «г» изменяется более чем один раз в выражении между двумя последовательно указывает Seq1 и seq2 (смотри ниже). Важно отметить, что оператор присваивания не вводит никакой точки последовательности.

$ 5/4- «За исключением особо оговоренных случаев, порядок оценки операндов отдельных операторов и подвыражениям отдельных выражений, и порядок, в котором побочные эффекты имеют место, это unspecified.53) Между предыдущей и следующей точкой последовательности скаляр объект должен иметь хранимую в нем величину модифицированного не более одного раза в вычисления выражения. Кроме того, предшествующее значение должно быть доступ только к де укажите значение для хранения. Требования настоящего пункта должны быть выполнены для каждого допустимого порядка подвыражений полного выражения; иначе поведение не определено.»

В C++ 0x

будет обновлять один раз я сам понимаю подробности обсуждения ссылается @litb.На данный момент я просто удаляю его

В C++ 0X однако, как я понимаю, нет понятия точек последовательности. Это выражение прекрасно и не вызывает неопределенное поведение. Это связано с тем, что эффект ++ на 'z' секвенирован перед побочным эффектом присваивания на 'z'.

$ 1,9/15- «За исключением особо оговоренных случаев, оценки операндами отдельных операторов и подвыражений отдельных выражений unsequenced [Примечание:. В выражении , который оценивается более чем один раз во время выполнение программы, unsequenced и виртуализированные неопределенна оценка его подвыражений не нужно проводить последовательно в разных оценках. -end примечание] Значение расчетов операндами оператора являются , упорядоченные до вычисления значения результата оператора. Если побочного эффект от скалярного объекта unsequenced по отношению к любому другим побочного эффекту на тот же скалярном объект или вычисление значения, используя значение одного и тот же скалярного объекта, поведения не определенно.

$ 3,9/9 - «Арифметические типов (3.9.1), перечислимых типов, типы указателей, указателя на типы членов (3.9.2), станд :: nullptr_t и резюме квалифицированных версии этих типы (3.9.3) - это , которые в совокупности называются скалярными типами ».

Обратите внимание, что в выражении 'z = z ++;' где z - скалярная переменная, побочные эффекты на «z» из-за оператора присваивания и постфиксного оператора ++ не подвержены последовательности (ни одна из них не секвенирована перед другой).

Благодаря @Prasoon для придания ценный вклад уточнить этот пост от оригинальной версии

+2

@Prasoon Saurav: где ты? – Chubsdad

+2

@Chubsdad: поведение будет неопределенным в зависимости от значений 'x' и' y'. Но мы имеем 'x = 1' и' y = 1', поэтому оценка '++ z' гарантирована, поэтому поведение будет неопределенным, потому что' z' изменяется более одного раза между двумя точками последовательности [назначение и преинкремент дважды измените 'z' без какой-либо промежуточной точки последовательности. Обратите внимание, что ваше сообщение содержит цитату из проекта C++ 0x. В C++ 0x 'i = ++ i' является четко определенным поведением. –

+0

Активируйте свой ответ сейчас. :) –

2

Простой способ узнать, если эта линия нормально или нет, пусть компилятор проверить. Например, gcc имеет the -Wsequence-point option (включен -Wall) для проверки наличия неопределенного поведения из-за отсутствия точек последовательности.

Ваша программа

int main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;/*is this fine?*/ 

    return 0; 
} 

производит это предупреждение:

 
x.c: In function 'main': 
x.c:6:5: warning: operation on 'z' may be undefined 
+0

Это расстраивает то, что gcc требует специальной опции для создания предупреждений об этом вместо того, чтобы просто генерировать 'movb $ 0,0' или эквивалент для такого кода. –

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