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)