<none>
- From
- Andrey Tarasevich ()
- To
- Vitaly Mayatskih
- Date
- 2002-09-28T01:34:37Z
- Area
- RU.ALGORITHMS
From: "Andrey Tarasevich" <atarasevich@telocity.com>
Fri Sep 27 2002 17:40, Vitaly Mayatskih wrote to Andrey Tarasevich:
AT>> Нет. Ни о каком выполнении справа налево в данном случае и речи быть
AT>> не может. Операции '^=' _ассоциируются_ справа налево. А в каком
AT>> порядке они _выполняются_ - не определено. Почувствуй разницу. Ни язык
AT>> С, ни язык С++ не определяют и никогда не определяли порядок
AT>> выполнения встроенных операций (кроме нескольких исключений типа && и
AT>> ||).
VM> Я категорически не согласен.
Это не вопрос согласия/несогласия. Это вопрос знания/незнания и
понимания/непонимания спецификации языка.
VM> На порядок группирования и
VM> вычисления операций ассоциативность влияет самым прямым образом.
Еще раз повторяю. Спецификация языка С++ черным по белому указывает в пункте
5/4, что порядок вычисления операндов операторов, порядок вычисления
подвыражений выражений и порядок возникновения побочных эффектов _не_
_определен_, за исключением случаев, где это специально оговорено. Операторы
присваивания не являются такими специально оговоренными случаями.
VM> Когда в
VM> выражении имеется несколько операторов одного приритета, то они
VM> применяются в соответствии с их ассоциативностью.
Популярное заблуждение. Это относится только к операторам, определенным
пользователем. А при использовании _встроенных_ операторов (т.е. при
манипуляции _скалярными_ типами, как сказано в 5/4) ассоциативность операторов
описывает только семантический смысл выражения (это что-то вроде
"канонического" порядка вычисления выражения), но никоим образом не определяет
конкретный порядок вычисления. Компилятор волен вычислять выражения как
угодно, главное чтобы результат соответствовал спецификации языка. В данном
случае спецификация языка говорит об этом выражении только одно -
неопределенное поведение.
Закроем на минутку глаза на это неопределенное поведение. Даже если бы порядок
выполнения операторов в данном случае был бы определен, это все равно ничего
бы не изменило. Момент и порядок возникновения _побочных_ _эффектов_ все равно
остается неопределенным. (Повторяю, изменение левой части оператора
присваивания является _побочным_ _эффектом_ оператора присваивания)
VM> Свойством
VM> коммутативности обладают только мультипликативные, аддитивные и
VM> поразрядные операции, порядок вычисления в таком случае зависит от
VM> компилятора. Но к составному присваиванию это никакого отношения не
VM> имеет.
Двойная ошибка.
Во-первых, здесь ты выделяешь операторы присваивания в какую-то "особенную"
группу по отношению к правилу 5/4. Это твои домыслы. Спецификация языка их ни
в какую особенную группу не выделяет.
Во-вторых, как уже говорил не раз, основной проблемой таких выражений является
неопределенность порядка возникновения _побочных_ _эффектов_ (а не
неопределенность порядка вычисления). Компилятор имеет право отложить все
побочные эффекты (т.е. собственно присваивания) на конец вычисления выражения
и выполнить их при этом в любом порядке. Т.е. компилятор в ответ на 'a ^= b ^=
a ^= b' имеет право скомпилировать вот такой код (псевдокод)
// Вычисление подвыражений
t1 = a ^ b;
t2 = b ^ t1;
t3 = a ^ t2;
// Выполнение побочных эффектов
a = t3;
b = t2;
a = t1;
Несложно видеть, что никакого "обмена" при этом не произойдет.
Bets regards,
Андрей.
P.S. Мы в глубоком оффтопике. Предлагаю перейти в su.c-cpp
--- ifmail v.2.15dev5
* Origin: FidoNet Online - http://www.fido-online.com (2:5020/400)