Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.01.22;
Скачать: 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 вся ветка

Текущий архив: 2006.01.22;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.029 c
9-1123486620
ПЛОВ
2005-08-08 11:37
2006.01.22
Вопрос по OpenGL


2-1136371371
psa247
2006-01-04 13:42
2006.01.22
ListView !


9-1123591873
Monsteria
2005-08-09 16:51
2006.01.22
Индекатор загрузки


14-1135398238
Дремучий
2005-12-24 07:23
2006.01.22
А надо ли делать автоматическое Windows Update?


2-1136548967
IK
2006-01-06 15:02
2006.01.22
WinWORD