Вниз
Скачать: CL | DM;

Небольшой вопросик по 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 вся ветка

Скачать: CL | DM;



Память: 0.51 MB
Время: 0.025 c
2-1136484770
Purgen
2006-01-05 21:12
2006.01.22
DLL


14-1135416752
Витёк
2005-12-24 12:32
2006.01.22
Как узнать число простое или нет?


1-1134561283
Antonn
2005-12-14 14:54
2006.01.22
Оконная тень


1-1135067057
Stanislav
2005-12-20 11:24
2006.01.22
Перемещение объекта в TScrollBox


2-1136440033
ezorcist
2006-01-05 08:47
2006.01.22
Изменить палитру на Image




   Наверх