Re: <none>
- From
- Andrey Tarasevich ()
- To
- Max Alekseyev
- Date
- 2002-09-30T11:48:20Z
- Area
- RU.ALGORITHMS
From: Andrey Tarasevich <atarasevich@telocity.com>
Max Alekseyev wrote:
> ...
> А что есть ассоциирование ("расставление скобок") как не определение порядка
> вычисления?
Ассоциирование есть определение, скажем так, "канонического" порядка
вычисления. Т.е. порядка, который однозначно определяет семантический смысл
выражения. Тем не менее в общем случае такой "канонический" порядок
вычисления не является единственным порядком вычисления. Компилятор вправе
выбрать абсюлютно любой порядок вычисления, главное чтобы результат
получился таким же, как и при "каноническом" порядке. Т.е. ассоциативность
говорит нам о том, каким будет результат выражения. Но она ничего не говорит
нам о том, каким образом это выражение будет вычисляться.
Более того, компилятор может не только произвольно варьировать порядок
вычисления подвыражений, но и способ их вычисления. Если в некотором
выражении использованы операторы умножения и сложения, это совсем не
означает, что при вычислении этого выражения компилятор обязан
последовательно выполнять умножения и сложения. Если компилятор сочтет
нужным, он может вычислить это выражение при помощи делений и сдвигов. Это
его личное дело. Главное чтобы результат получился правильным.
Ассоциативность говорит нам, что результат выражения 2 + 2 * 2 равен 6, а не
8. А вычислять это выражение компилятор может и как 2 + 2 + 2 (заменив
умножение на сложение), и как 2 * (2 + 1) (вынеся 2 за скобки). Главное
чтобы в результате получилось 6.
Все вышесказанное относится только к скалярным типам и встроенным
операторам. Пользовательские операторы - совсем другая история.
> Цитирую стандарт пункт 6.2:
> "Unary operators and assignment operators are right-associative [...] For
> example, a=b=c means a=(b=c) [...]"
> ...
А это в свою очередь означает, что в переменную 'a' долно попасть значение
переменной 'c', но так, как будто оно перед этим прошло через переменную
'b'. Это совсем не означает, что сначала должно произойти занесение нового
значения в переменную 'b', а потом оттуда - в 'a'. Нет. Если компилятор
захочет, он может сначала занести правильное результирующее значение в
переменную 'a', а потом - в 'b'.
Например вот в таком примере
unsigned a;
unsigned char b;
unsigned c = 500;
a = b = c;
на платформе с 8-мибитным типом char, переменная 'a' должна получить
значение 244 (500 mod 256). Это именно то, о чем говорит нам
ассоциативность. Не более. Т.е. ассо
А в каком порядке компилятор выполнит присваивания - его дело. Может так
b = c;
a = b;
А может и так
a = (unsignecd char) c;
b = c;
Оба варианта - правильные.
--
Best regards,
Андрей.
--- ifmail v.2.15dev5
* Origin: good enough (2:5020/400)