Определяем модуль
Код:
MODULE test;
IMPORT Out;
TYPE
Counter = POINTER TO RECORD
value: INTEGER;
END;
VAR
i: Counter;
PROCEDURE (i: Counter) pp(): INTEGER;
BEGIN
INC(i.value);
RETURN i.value
END pp;
PROCEDURE (i: Counter) ppp(): INTEGER;
BEGIN
INC(i.value,2);
RETURN i.value
END ppp;
PROCEDURE (i: Counter) PP(): Counter;
BEGIN
INC(i.value);
RETURN i
END PP;
PROCEDURE Check(i1,i2,i3,i4: Counter);
BEGIN
Out.String('i1 = ');
Out.Int(i1.value,0);
Out.Ln;
Out.String('i2 = ');
Out.Int(i2.value,0);
Out.Ln;
Out.String('i3 = ');
Out.Int(i3.value,0);
Out.Ln;
Out.String('i4 = ');
Out.Int(i4.value,0);
Out.Ln;
END Check;
PROCEDURE check(i1,i2,i3,i4: INTEGER);
BEGIN
Out.String('i1 = ');
Out.Int(i1,0);
Out.Ln;
Out.String('i2 = ');
Out.Int(i2,0);
Out.Ln;
Out.String('i3 = ');
Out.Int(i3,0);
Out.Ln;
Out.String('i4 = ');
Out.Int(i4,0);
Out.Ln
END check;
BEGIN
NEW(i);
i.value := 10;
Out.String('the initial value: ');
Out.Int(i.value,0);
Out.Ln;
Out.String('the result of the operation pp + pp: ');
Out.Int(i.pp() + i.pp(),0);
Out.Ln;
Out.String('the final value: ');
Out.Int(i.value,0);
Out.Ln;
i.value := 10;
Out.String('the initial value: ');
Out.Int(i.value,0);
Out.Ln;
Out.String('the result of the operation ppp + pp: ');
Out.Int(i.ppp() + i.pp(),0);
Out.Ln;
Out.String('the final value: ');
Out.Int(i.value,0);
Out.Ln;
i.value := 10;
Out.String('the initial value: ');
Out.Int(i.value,0);
Out.Ln;
Out.String('the result of the operation pp + ppp: ');
Out.Int(i.pp() + i.ppp(),0);
Out.Ln;
Out.String('the final value: ');
Out.Int(i.value,0);
Out.Ln;
Out.Ln;
i.value := 10;
Out.String('the initial value with pointers: ');
Out.Int(i.value,0);
Out.Ln;
Check( i.PP() , i.PP() , i.PP() , i.PP() );
Out.Ln;
i.value := 10;
Out.String('the initial value with values: ');
Out.Int(i.value,0);
Out.Ln;
check( i.pp() , i.pp() , i.pp() , i.pp() );
Out.Ln
END test.
На выходе с Ofront+ и oo2c получаем:
Код:
the initial value: 10
the result of the operation pp + pp: 23
the final value: 12
the initial value: 10
the result of the operation ppp + pp: 25
the final value: 13
the initial value: 10
the result of the operation pp + ppp: 24
the final value: 13
the initial value with pointers: 10
i1 = 14
i2 = 14
i3 = 14
i4 = 14
the initial value with values: 10
i1 = 14
i2 = 13
i3 = 12
i4 = 11
Отсюда делаем вывод, что в процедурах вычисление аргументов идёт с конца списка, а в выражениях с оператором "+" — с начала. Как видно, если выражения с последствиями, порядок важен.
Это где-нибудь вообще задокументировано или оставлено на откуп автора компилятора? В последнем случае получаем неопределённое поведение.