Форум: "Прочее";
Текущий архив: 2008.01.20;
Скачать: [xml.tar.bz2];
ВнизРезультат трехчасовых поисков ошибки в проекте :) Найти похожие ветки
← →
Riply © (2007-12-10 17:08) [0]Здравствуйте !
Допустим, у нас есть две ф-ии:function Funct1(var Param: integer): integer;
begin
if Param = 0 then inc(Param, 1);
Result := Param;
end;
function Funct2(var Param: integer): integer;
begin
if Param = 0 then inc(Param, 2);
Result := Param;
end;
Что мы увидим в сообщении:Param := 0;
ShowMessage(IntToStr(Funct1(Param) + Funct2(Param)));
Чур Delphi не пользоваться :)
Пол дня убила на поиск ошибки, зато новые знания :)
← →
Palladin © (2007-12-10 17:10) [1]3 и увидим
← →
Rouse_ © (2007-12-10 17:10) [2]1?
← →
Alkid © (2007-12-10 17:11) [3]Мда, а ещё кто-то за конструкции вида i = i++ + 1 С/C++ извращением считает...
← →
Palladin © (2007-12-10 17:11) [4]ой... 4 :)
← →
Сергей М. © (2007-12-10 17:11) [5]
> Пол дня убила на поиск ошибки
Бедняга).. Целых пол-дня !!
Нет бы сразу пройтись отладчиком и выяснить, где таятся грабли)
← →
Rouse_ © (2007-12-10 17:12) [6]А, не, там еще сложение ж у тебя :)
Двойку увидим :)
← →
Riply © (2007-12-10 17:13) [7]Верных ответов, пока, нет :)
← →
Palladin © (2007-12-10 17:14) [8]
> Rouse_ © (10.12.07 17:12) [6]
А var не заметил? :)
первая функция возвратит 1, изменит значение переменной на 1
вторая функция возвратит 3
1+3=4
← →
Riply © (2007-12-10 17:14) [9]> [6] Rouse_ © (10.12.07 17:12)
Когда отправляла, твоего ответа не видела.
Правильно !
:)
← →
Rouse_ © (2007-12-10 17:14) [10]
> Верных ответов, пока, нет :)
Проверил - показывает двойку :)
← →
Rouse_ © (2007-12-10 17:15) [11]
> вторая функция возвратит 3
Нет, т.к. param уже будет не 0 а единица :)
← →
Palladin © (2007-12-10 17:16) [12]млин... условие if забыл... розыч, посыпаю голову пеплом
2 возвратит
← →
Riply © (2007-12-10 17:16) [13]>[5] Сергей М. © (10.12.07 17:11)
> Бедняга).. Целых пол-дня !!
> Нет бы сразу пройтись отладчиком и выяснить, где таятся грабли)
В свое оправдание скажу, что настоящая ситуация выглядит не совсем так :)
Это ее суть :)
← →
Reindeer Moss Eater © (2007-12-10 17:16) [14]2
← →
Riply © (2007-12-10 17:18) [15]Я когда искала ошибку, на автомате полагала, что
сначала выполниться Funct1, а потом Funct2
← →
Riply © (2007-12-10 17:20) [16]> [12] Palladin © (10.12.07 17:16)
> [14] Reindeer Moss Eater © (10.12.07 17:16)
Я всегда говорила, что настоящие программисты здесь :)
Но Rouse_ первым увидел подвох :)
← →
Rouse_ © (2007-12-10 17:21) [17]
> на автомате полагала, что
> сначала выполниться Funct1, а потом Funct2
Так оно так и происходит :) Сначала первая выполняется а потом вторая :)
← →
Palladin © (2007-12-10 17:22) [18]
> Riply © (10.12.07 17:20) [16]
:) я if не учел при внутреннемозговом исполнениии...
вывод: пиво - враг интерпритации действий...
← →
Rouse_ © (2007-12-10 17:22) [19]
> пиво - враг интерпритации действий...
Ты на работе под пивом кодишь? Суров... :)
← →
Сергей М. © (2007-12-10 17:23) [20]
> Riply © (10.12.07 17:16) [13]
> настоящая ситуация выглядит не совсем так
А неважно как она выглядит)
Трассировка мгновенно расставила бы все точки над i)
← →
Palladin © (2007-12-10 17:23) [21]
> Так оно так и происходит :) Сначала первая выполняется а
> потом вторая :)
:) вот только во второй значение уже другое ибо var...
диагноз: ай ай ай... :)
← →
Palladin © (2007-12-10 17:24) [22]
> Rouse_ © (10.12.07 17:22) [19]
а кто сказал что я сейчас кодю? :) я в форуме сидю... :)
вот... пытался интерпретировать... и не замечая мелких деталей рванувшись к цели - промазал :)
← →
Riply © (2007-12-10 17:24) [23]> [17] Rouse_ © (10.12.07 17:21)
> Так оно так и происходит :) Сначала первая выполняется а потом вторая :)
???
> [18] Palladin © (10.12.07 17:22)
> :) я if не учел при внутреннемозговом исполнениии...
> вывод: пиво - враг интерпритации действий...
:)
← →
guav © (2007-12-10 17:26) [24]Напоминает
int i = 5;
cout << ++i + ++i;
где разные компиляторы разный результат дают
← →
Rouse_ © (2007-12-10 17:26) [25]
> Riply © (10.12.07 17:24) [23]
> ???
Ну ты посмотри в отладчике, при вызове ShowMessage сначала происходит выполнение первой функции, потом передается управление на вторую, потом конкатенация и вызов IntToStr :)Unit38.pas.118: ShowMessage(IntToStr(Funct1(Param) + Funct2(Param)));
0045EF3F 8D45FC lea eax,[ebp-$04]
0045EF42 E8C1FFFFFF call Funct1
0045EF47 8BD8 mov ebx,eax
0045EF49 8D45FC lea eax,[ebp-$04]
0045EF4C E8C3FFFFFF call Funct2
0045EF51 03D8 add ebx,eax
0045EF53 8BC3 mov eax,ebx
0045EF55 8D55F8 lea edx,[ebp-$08]
0045EF58 E8AF98FAFF call IntToStr
← →
stone © (2007-12-10 17:30) [26]
> Riply © (10.12.07 17:08)
Задачку про буратино и яблоки знаешь?
← →
DiamondShark © (2007-12-10 17:34) [27]
> Чур Delphi не пользоваться :)
А без этого -- гадание на кофейной гуще.
Потому что порядок, в котором вызовутся функции никем не гарантирован.
> guav © (10.12.07 17:26) [24]
> Напоминает
> int i = 5;
> cout << ++i + ++i;
> где разные компиляторы разный результат дают
Совершенно верно. Именно поэтому операторы с побочным эффектом должны сдохнуть.
Из-за наличия таких операторов приходится либо фиксировать порядок вычисления термов в выражении (и подложить свинью оптимизатору), либо поиметь граблей на разных компиляторах и оптимизаторах.
← →
Palladin © (2007-12-10 17:36) [28]
> DiamondShark © (10.12.07 17:34) [27]
Эт почему не гарантирован? Какой то delphi компилятор строит выполнение выражения справа налево чтоли?
← →
Riply © (2007-12-10 17:36) [29]> [26] stone © (10.12.07 17:30)
> Задачку про буратино и яблоки знаешь?
Неа.
> [27] DiamondShark © (10.12.07 17:34)
> Потому что порядок, в котором вызовутся функции никем не гарантирован.
А можно аргументировать ?
← →
Rouse_ © (2007-12-10 17:39) [30]Кстати, а у кого FreePascal есть? Проверьте там очередность вызова.
← →
Riply © (2007-12-10 17:44) [31]> [25] Rouse_ © (10.12.07 17:26)
> Ну ты посмотри в отладчике,
Смотрю и не могу понять, почему тогда возвращается 2 ?
← →
Palladin © (2007-12-10 17:46) [32]
> Rouse_ © (10.12.07 17:39) [30]
точно такая же... но я бы удивился если бы это было не так..
> Riply © (10.12.07 17:44) [31]
потому что параметр передан по ссылке, а не по значению... соответственно когда выполнилась функция func1 само значение param уже 1 соответственно при переходе к исполнению func2 оно тоже 1
← →
Palladin © (2007-12-10 17:47) [33]param имеется ввиду сама переменная парам а не та что в параметрах
← →
Германн © (2007-12-10 17:47) [34]
> Смотрю и не могу понять, почему тогда возвращается 2 ?
>
Я тоже не могу понять.
← →
Германн © (2007-12-10 17:49) [35]
> Palladin © (10.12.07 17:47) [33]
>
> param имеется ввиду сама переменная парам а не та что в
> параметрах
>
А как же АСМ в Rouse_ © (10.12.07 17:26) [25]?
← →
Riply © (2007-12-10 17:51) [36]> [32] Palladin © (10.12.07 17:46)
> потому что параметр передан по ссылке, а не по значению...
>соответственно когда выполнилась функция func1 само значение param уже 1
> соответственно при переходе к исполнению func2 оно тоже 1
но тогда(при переходе к исполнению func2 оно тоже 1) func2 ничего бы не изменила и мы бы увидели 1
← →
Rouse_ © (2007-12-10 17:51) [37]
> Смотрю и не могу понять, почему тогда возвращается 2 ?
Ок, разжую :)Unit38.pas.117: Param := 0;
0045EF3A 33C0 xor eax,eax // чистим Param
0045EF3C 8945FC mov [ebp-$04],eax // помещает его на стек
Unit38.pas.118: ShowMessage(IntToStr(Funct1(Param) + Funct2(Param)));
0045EF3F 8D45FC lea eax,[ebp-$04] // готовим ссылку на параметр
0045EF42 E8C1FFFFFF call Funct1 // дергаем функцию
0045EF47 8BD8 mov ebx,eax // сохраняем результат функции во временном регистре (в ebp-$04 также лежит единица, т.к. ByRef)
0045EF49 8D45FC lea eax,[ebp-$04] // готовим ссылку на параметр
0045EF4C E8C3FFFFFF call Funct2 // дергаем вторую функцию
// она также вернула единицу т.к. не выполнилось условие if Param = 0 then
0045EF51 03D8 add ebx,eax // складываем оба результата
0045EF53 8BC3 mov eax,ebx // ну а дальше IntToStr и ShowMessage
0045EF55 8D55F8 lea edx,[ebp-$08]
0045EF58 E8AF98FAFF call IntToStr
0045EF5D 8B45F8 mov eax,[ebp-$08]
0045EF60 E87BE5FCFF call ShowMessage
← →
Rouse_ © (2007-12-10 17:52) [38]
> func2 ничего бы не изменила и мы бы увидели 1
Не изменила - она вернула то, что ей было переданно, а передано ей было уже 1 а не ноль :)
← →
Palladin © (2007-12-10 17:54) [39]
> Riply © (10.12.07 17:51) [36]
ну мля... в параметрах исполнения func один передается не значение 0, а ссылка на саму переменную, и именна сама переменная после отработки функции меняет значение, после идет исполнение func два, которой уже передано (и кстати не важно как var или const или просто в стек засунуто) значение 1 потому что func один уже поменяла значение...
← →
Riply © (2007-12-10 17:54) [40]> [37] Rouse_ © (10.12.07 17:51)
> Ок, разжую :)
Спасибо.
Страницы: 1 2 3 4 вся ветка
Форум: "Прочее";
Текущий архив: 2008.01.20;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.041 c