Страница 1 из 1
Функции в качестве параметров процедур
Добавлено:
03.05.2013 21:22:21
Ro_jA
Товарищи,подскажите, это баг или фича?
Берем, скажем, процедуру с тремя параметрами. Эти параметры задаем с помощью трёх функций, работающих со строкой. Во время работы программы функции вызываются в нормальном порядке, а результаты в процедуру возвращаются в обратном. Вот пример:
- Код: Выделить всё
var
a:string;
i:integer;
function f1(b:string):integer;
begin
inc(i);
writeln('f#',i);
f1:=ord(b[1]);
writeln(chr(f1));
delete(a,1,1);
writeln
end;
procedure p1(a,b,c:integer);
begin
writeln(chr(a));
writeln(chr(b));
writeln(chr(c))
end;
begin
i:=0;
readln(a);
p1(f1(a),f1(a),f1(a));
readln
end.
Вводим строку 'abc'
На экране видим:
f#1
a
f#2
b
f#3
c
{то есть функции вызываются в правильном порядке, но потом:}
c
b
a
{то есть процедура берет их в обратном.}
Очень, знаете ли, обидная и труднообнаруживаемая проблема.
Компилятор 2.6.2.
Re: Функции в качестве параметров процедур
Добавлено:
03.05.2013 21:53:36
Sergei I. Gorelkin
Фича.
Компилятор вычисляет аргументы в произвольном порядке, который может зависеть от типа вызываемой процедуры и целевой платформы.
Re: Функции в качестве параметров процедур
Добавлено:
03.05.2013 22:06:21
Ro_jA
И какая же практическая польза от этой фичи? Каким образом мне при последующем написании программ удостовериться, что все вычисляется в нужном порядке?
Re: Функции в качестве параметров процедур
Добавлено:
03.05.2013 22:38:41
Sergei I. Gorelkin
- Код: Выделить всё
var
t1,t2,t3: integer;
begin
t1:=f1(a);
t2:=f1(a);
t3:=f1(a);
p1(t1,t2,t3);
end;
Код, зависящий от порядка вычисления аргументов функции, писать не нужно.
Re: Функции в качестве параметров процедур
Добавлено:
03.05.2013 22:39:32
runewalsh
Записывать во временные переменные в нужном порядке. Фича оправданна и имеет место в абсолютном большинстве компилируемых языков, т. к. предоставляет компилятору простор для оптимизации. А вот вызывать зависящие друг от друга функции в пределах одной точки следования — опасно; даже в шарподжавах, где порядок определён, это как минимум моветон.
UPD: ну вот, меня опередили. ^^
Re: Функции в качестве параметров процедур
Добавлено:
03.05.2013 22:53:28
Ro_jA
Ну что ж, спасибо за советы. Непонятно, почему в документации ни слова на этот счет. В ref вообще ничего,а в prog я нашел строчку "If a function is called that returns a variable of type String, Set, Record, Object or
Array, then an address to store the function result in, is also passed to the procedure." которая,похоже вообще не о том.
Эмм, а как закрыть тему?
Re: Функции в качестве параметров процедур
Добавлено:
04.05.2013 15:40:10
absdjfh
Ro_jA писал(а):Непонятно, почему в документации ни слова на этот счет.
Ну вот как нет, если есть? Глава 12, reference guide, expressions:
Remark: The order in which expressions of the same precedence are evaluated is not guaranteed to be left-to-right. In general, no assumptions on which expression is evaluated first should be made in such a case. The compiler will decide which expression to evaluate first based on optimization rules. Thus, in the following expression:
a := g(3) + f(2);
f(2) may be executed before g(3). This behaviour is distinctly different from Delphi or Turbo Pascal.
If one expression must be executed before the other, it is necessary to split up the statement using temporary results:
e1 := g(3);
a := e1 + f(2);
Re: Функции в качестве параметров процедур
Добавлено:
07.05.2013 20:32:24
Ro_jA
Как раз хотел задать вопрос насчет порядка вычислений в этом операторе. Я не нашел этого потому, что искал в процедурах и функциях, а до выражений руки не дошли. Могли бы и там упомянуть, на самом деле. В любом случае спасибо.
Re: Функции в качестве параметров процедур
Добавлено:
09.05.2013 14:43:11
Mirage
Причем тут порядок вычисления выражений?
Порядок передачи параметров зависит от calling convention. Например, можно попробовать пометить функцию p1 как pascal.
Порядок вычисления параметров, конечно, может и отличаться от порядка их передачи, но на практике это врядли.
Конечно, закладываться на определенный порядок нельзя. Т.к. он неопределенный в общем случае.
Re: Функции в качестве параметров процедур
Добавлено:
09.05.2013 15:47:17
absdjfh
Mirage писал(а):Т.к. он неопределенный в общем случае.
Он (порядок вычисления функций в выражениях и вызовах функций) неопределенный только в случае компилятора FPC. В TP (и, вероятно, delphi) можно было закладываться на такой порядок, и программа выводила (и выводит сейчас) ожидаемый (по человеческой логике) результат для любого варианта передачи параметров.
Самый правильный вариант, конечно, - не писать функций с побочными эффектами, особенно если без этого можно легко обойтись.