Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.04.15;
Скачать: [xml.tar.bz2];

Вниз

Порядок выполнения вложенных функций   Найти похожие ветки 

 
Loginov Dmitry ©   (2007-03-23 09:53) [0]

Пусть есть 2 функции:

function Func1: Integer;
begin

end;

function Func2: Integer;
begin

end;


И эти функции участвуют как аргументы вызова третьей функции

function Func3(A, B: Integer): Integer;
begin

end;


И сам вызов:
Value := Func3(Func1, Func2);

Вопрос:

Какая функция будет выполнена раньше Func1 или Func2. Порядок вызовов этих функций предопределен (типа слева-направа) или порядок вызова ложится на совесть компилятора?

Сам всегда почему-то считал, что вызов идет слево-направо (сначала Func1 а потом Func2). Однако счас столкнулся с обратным. Не знаю, что это - баг Delphi 7 или так и должно быть и определенная последовательность вызовов Func1 и Func2 никем не гарантируется (но тогда где упоминание об этом в документации)?


 
Loginov Dmitry ©   (2007-03-23 09:58) [1]

Епсь! Функция объявлена как StdCall. Какой гад ее так объявил!

Извиняйте, вопрос снят :)))


 
ЮЮ ©   (2007-03-23 10:02) [2]

> Однако счас столкнулся с обратным

А какая разница? sin(0) всегда 0, независимо от того считал перед этим cos() или нет.
А если уж закладываешься на порядок выполнения, не поленись обеспечить порядок вызова явно, хотя бы так:

f1 := Func1;
Value := Func3(f1, Func2);

З.Ы. Станные какие-то функции - без параметров? Через глобальные переменные что-ли "общаются"?


 
Чапаев ©   (2007-03-23 10:04) [3]

> Сам всегда почему-то считал, что вызов идет слево-направо
Как я и полагал... Для register функции с >=5 параметрами сначала "слева направо" вычисляются параметры, начиная с четвёртого, а затем превые три параметра "справа налево".


 
Чапаев ©   (2007-03-23 10:06) [4]

Эх... Только соберёшься хоть какое-нибудь исследование провести, как тут же оказывается, что всё дело в неправильном объявлении. :-\


 
Loginov Dmitry ©   (2007-03-23 10:14) [5]

> Епсь! Функция объявлена как StdCall. Какой гад ее так объявил!
>
>
> Извиняйте, вопрос снят :)))


Поспешил. Убрал StdCall - не изменилось ровным счетом ничего (траблы остались :(  )


 
MBo ©   (2007-03-23 10:17) [6]

Нет никаких траблов. Если у функций имеется побочное действие, вычисляй их заранее, т.к. порядок вычисления при таком вызове не предопределен.


 
Loginov Dmitry ©   (2007-03-23 10:21) [7]

В общем функция объявлена так:


procedure ShowRpt(const TextRep, HtmlRep, Caption:string); stdcall;


Вызывается так:

ShowRpt(GetOldReport(...), GetNewReport(...), "Расходная накладная");


Порядок вызова вложенных функций - принципиальный. Без вызова GetOldReport() не сработает GetNewReport(), так как действительно используются глобальные переменные, которым устанавливается нужное значение при работе GetOldReport(). Я могу конечно поменять местами  GetNewReport() и GetOldReport(), однако где гарантия, что компилятор опять не изменит порядок их вызова?


 
Loginov Dmitry ©   (2007-03-23 10:23) [8]

> Нет никаких траблов. Если у функций имеется побочное действие,
> вычисляй их заранее, т.к. порядок вычисления при таком
> вызове не предопределен.


Ясно. Придется все-же вынести выполнение функций GetNewReport() и GetOldReport() до ShowRpt().
Что ж. Буду зато знать про эти грабли.


 
Loginov Dmitry ©   (2007-03-23 10:49) [9]

Вычисление аргументов функций в случайном порядке это что - неписанная истина, или об этом можно где-нибудь что-то прочесть?


 
Чапаев ©   (2007-03-23 11:05) [10]

Почитай, как именно параметры помещаются в стек, все ли помещаются... Потом на бумажке сам попробуй расписать, как именно их нужно поместить в твоём конкретном случае. Если к своей функции припишешь конвенцию вызова pascal, всё будет как тебе надо, например.


 
Loginov Dmitry ©   (2007-03-23 11:22) [11]

Причем здесь то, как параметры помещаются в стек? Порядок вычисления аргументов функции не имеет отношения к порядку помещения данных в стек.


 
Плохиш ©   (2007-03-23 11:27) [12]


> Loginov Dmitry ©   (23.03.07 11:22) [11]
> Причем здесь то, как параметры помещаются в стек?

Когда параметр понадобился, тогда он и вычисляется. Т.ч. самая прямая зависимость.


 
Чапаев ©   (2007-03-23 11:27) [13]

> Порядок вычисления аргументов функции не имеет отношения
> к порядку помещения данных в стек.
Тааа ты шоооо?


 
Loginov Dmitry ©   (2007-03-23 11:45) [14]

> Тааа ты шоооо?


Хотите сказать, что в моем случае, не зависимо от stdcall, параметры все-равно передаются в функцию справа-налево?


 
Чапаев ©   (2007-03-23 11:47) [15]

Блиииин. Ну перечти ещё раз мои посты, а? Если объявить функцию как pascal, параметры передадутся строго слева направо. Если как stdcall, передадутся справа налево. Если не уточнять ничего (что равнозначно register), сначала вычислятся с четвёртого до последнего слева направо, затем вычислятся первые три справа налево. Что ещё неясно?


 
Loginov Dmitry ©   (2007-03-23 11:59) [16]

В моем случае всего 3 параметра. Т.е. получим, что при register они вычисляются права налево, потому как [15]. А при stdcall они вычисляются справо налево, потому как такой порядок передачи аргументов в стек?


 
homm ©   (2007-03-23 12:02) [17]

> Т.е. получим, что при register они вычисляются права налево

откуда данные. При register имхо не важен порядок, как оптимизатор решит.


 
Loginov Dmitry ©   (2007-03-23 12:03) [18]

> откуда данные.


см [15] :)


 
Чапаев ©   (2007-03-23 12:09) [19]

> [17] homm ©   (23.03.07 12:02)
В общем да, решает оптимизатор. Но в протестированных случайх оптимизатор решает вычислять третий, второй, затем первый параметр. ;-)


 
homm ©   (2007-03-23 12:09) [20]

> см [15] :)

А, тогда да! :)

В принцепе как-то сомнителен такой принцип. Тоже стало интересно, дома проверю, если время найду.


 
Kerk ©   (2007-03-23 12:10) [21]

Баян :)


 
Loginov Dmitry ©   (2007-03-23 15:11) [22]

Что-то эта фича не согласуется со справкой. А на заборе писано:

The register and pascal conventions pass parameters from left to right; that is, the left most parameter is evaluated and passed first and the rightmost parameter is evaluated and passed last.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2007.04.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.045 c
15-1174561110
ArtemESC
2007-03-22 13:58
2007.04.15
Думаю...


15-1173723374
Ringo
2007-03-12 21:16
2007.04.15
Вэб-камеры по всему миру.


2-1174556130
student:)
2007-03-22 12:35
2007.04.15
VPN на delphi


15-1174410138
Knight
2007-03-20 20:02
2007.04.15
Тестовая&#133 просьба не удалять.


15-1174150455
Real
2007-03-17 19:54
2007.04.15
Микроволновка - что можно приготовить?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский