Форум: "Потрепаться";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
ВнизНебольшой вопросик по Delphi Найти похожие ветки
← →
Mystic © (2005-12-26 19:39) [0]Какое сообщение выведет следующий исходник при вызове Test_01?
Ответить без запуска программы и сравнить результаты :)
var
GlobalVar: string;
procedure Test_03;
begin
GlobalVar := "New test value";
end;
procedure Test_02(const Arg: string);
begin
Test_03;
ShowMessage(Arg);
end;
procedure Test_01;
begin
GlobalVar := "Test string";
Test_02(GlobalVar);
end;
{procedure TForm1.Button1Click(Sender: TObject);
begin
Test_01;
end;}
← →
Anatoly Podgoretsky © (2005-12-26 19:43) [1]Не тяжело и запустить.
← →
Карелин Артем © (2005-12-26 19:43) [2]Программа выполнила недопустимую операцию и будет закрыта.
← →
Igorek © (2005-12-26 19:51) [3]OK
Project1
← →
GuAV © (2005-12-26 19:51) [4]Отвечаю без запуска: думаю, в GlobalVar сначала копируется "Test string" , затем "New test value" , но выводится "Test string", т.к. с момента присвоения GlobalVar := "New test value"; GlobalVar уже новый, а Arg старый, только число ссылок уменьшилось.
Запустил - удивился.
← →
umbra © (2005-12-26 19:56) [5]но Arg передается по ссылке. По идее должно выводить "New test value".
← →
GuAV © (2005-12-26 19:59) [6]
> но Arg передается по ссылке.
Какой по ссылке, const - это по значению (как и без модификатора, только с запретом на изменение).
Другое дело, что значение сторки - это уже сылка...
← →
umbra © (2005-12-26 20:01) [7]да, ошибка у меня вышла :(
← →
Mystic © (2005-12-26 20:07) [8]> OK
> Project1
Типа твой ответ "OK", но выдало "Project1"?
← →
GuAV © (2005-12-26 20:08) [9]Хотя навучное объяснение сему феномену у мя есть :-)
Счёт ссылок не был увеличен при передаче, присвоили GlobalVar как будто внутри вызывающего, тогда, как замечено в [4], число ссылок уменьшилось, и строка освобождена. В Arg отныне мусор. Вновь выделенная строка Project1 была выделенна по тожу же адресу что и Arg.
Кстати пример интересный, тут даже Uniquestring не поможет, со счётом ссылок всё верно...
← →
Mystic © (2005-12-26 20:13) [10]> GuAV © (26.12.05 20:08) [9]
:) Ловля похожего бага у меня в боевых условиях заняло недавно 1.5 часа :) Помогло CPU Window и в результате родился такой примерчик :) Может кому-то будет полезно :)
← →
Джо © (2005-12-26 20:15) [11]Global variables must die!
:^)
← →
GuAV © (2005-12-26 20:28) [12]
> :) Ловля похожего бага у меня в боевых условиях
Ну конечно, сам такое вред ли придумаешь... я тут тоже неск месяцев назад задачку про синтаксис кидал ;)
> Может кому-то будет полезно :)
В данном случае мне теперь всё ясно - фактически, освобождение данных, переданных по ссылке, до завершение вызвавшей подпрограммы. Но и освобождение и ссылка замаскировано под ключевым словомstring
. Спасибо. Теперь буду предупреждён ;)
PS: сразу хотел написать что результат зависит от директив компилятора - тогда бы я угадал.
← →
GuAV © (2005-12-26 20:29) [13]
>Global variables must die!
> :^)
Ой ну было бы поле класса, а процедуры методами, и ШО ? ;-)
← →
ZeroDivide © (2005-12-26 20:32) [14]Проблема в const!!!
← →
GuAV © (2005-12-26 20:35) [15]
> Проблема в const!!!
Да. Можно и так посмотреть - без const в вызываемой увеличистя счёт ссылок.
А так, действительно, меняем переменную, которая не должна быть изменена. И получаем заслужено.
← →
Mystic © (2005-12-26 20:46) [16]> И получаем заслужено.
Вся проблема в том, что код выглядит достаточно естественно... И вроде бы ничего не предвещает столь зловещего финала :) Еще один пример в пользу того, как важно знать мат. часть :)
← →
ZeroDivide © (2005-12-26 20:47) [17]
> Можно и так посмотреть
Нужно!
Const вообще зачем используется? RTFM!!!
← →
GuAV © (2005-12-26 20:57) [18]
> важно знать мат. часть :)
Матчасть... сам же признался что CPU юзал ;-)
← →
Anatoly Podgoretsky © (2005-12-26 21:30) [19]Mystic © (26.12.05 20:46) [16]
Вся проблема в том, что код выглядит достаточно естественно... И вроде бы ничего не предвещает столь зловещего
Почему же естественно, вот здесь const Arg:, вместо var
← →
Anatoly Podgoretsky © (2005-12-26 21:31) [20]И за одно виден вред глобальных переменных.
← →
Mystic © (2005-12-27 11:36) [21]> И за одно виден вред глобальных переменных.
В общем, если обернуть методы Test_XX одним классом, а GlobalVar Сделать полем класса, то проблема не исчезнет :)
> Почему же естественно, вот здесь const Arg:, вместо var
Естественно, потому что слово const подразумевает два умолчания, но про второе все забывают. Первое умолчание --- аргумент не должен изменяться в функции (это может проверить компилятор). И второе --- объект должен существовать на протяжении всего вызова функции (тут компилятор бессилен).
← →
Rouse_ © (2005-12-27 11:58) [22]Никакого не выведет - у тебя же отбработчик клика на кнопке закоментарен :)
← →
Igorek © (2005-12-27 12:17) [23]
> Mystic © (26.12.05 20:07) [8]
> > OK
> > Project1
>
> Типа твой ответ "OK", но выдало "Project1"?
Оно выдавало оба варианта. Своего ответа у меня не было.
← →
Mystic © (2005-12-27 13:12) [24]> Никакого не выведет - у тебя же отбработчик клика на кнопке
> закоментарен :)
А он не нужен, потому чтовопрос стоит: какое сообщение выведет следующий исходник при вызове Test_01?
← →
raidan © (2005-12-27 14:07) [25]Действительно интересно :)
← →
Rouse_ © (2005-12-27 14:31) [26]
> какое сообщение выведет следующий исходник при вызове Test_01?
Так вот именно следующий исходник ничего и не выведет :)))
← →
VirEx © (2005-12-27 15:09) [27]"Test string" но ведь тут одновременно с выводом меняется и значение переменной, должно быть будет испорченное значение
← →
VirEx © (2005-12-27 15:17) [28]оппа, делаем:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,dialogs;
var
GlobalVar: string;
procedure Test_03;
begin
GlobalVar := "New test value";
end;
procedure Test_02(const Arg: string);
begin
Test_03;
ShowMessage(Arg);
end;
procedure Test_01;
begin
GlobalVar := "Test string";
Test_02(GlobalVar);
end;
begin
Test_01;
end.
и выводится Test str↖ т.е. переменная уже испорчена
делаем без {$APPTYPE CONSOLE} и выводится Project1
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.053 c