<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)