Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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
2-1135852497
Dmitrij_K
2005-12-29 13:34
2006.01.22
Ускорение поиска файлов


2-1136534695
Zhekson
2006-01-06 11:04
2006.01.22
Фильтрация и перебор записей


14-1136038965
SPeller
2005-12-31 17:22
2006.01.22
Принимайте эстафету! :)


2-1136034543
PaNDa000
2005-12-31 16:09
2006.01.22
Сети


14-1135198030
Gero
2005-12-21 23:47
2006.01.22
Диалог поиска в IE





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский