Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему функция возвращает данные, которые ей недоступны [D7, Win2k, WinXP]


Страницы:   1 2 3 4 5

gosha67 ©   (2006-09-26 16:49:00) 

Здравствуйте уважаемые.
Я программист с некоторым опытом, но только сегодня я обнаружил сие недоразумение. Объясните мне пожалуйста почему в конечном итоге Data := 'some text bla bla bla ....'? По идее она должна быть равно только 'bla bla bla'. Загадка какая-то.
function GetSomeData: string;
var i : integer;
begin
 for i := 1 to 20 do
 begin
   Result := Result + ' bla bla bla';
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Data : string;
begin
 Data := 'some text';
 Data := GetSomeData;
 ShowMessage(Data);
end;


oxffff   (2006-09-27 12:34:00) [61]

Когда объявляется

a:string;
begin
....

то происходит

Push 0, а не sub esp,4.

Поэтому переменная A уже инициализированна


Игорь Шевченко   (2006-09-27 12:29:00) [62]

zamtmn ©   (27.09.06 12:15) [19]


> если бы компилятор не позаботился о result, то result вполне
> бы указывал на недопустимое значение

В твоем примере слова Result нету, это раз.


> глобальный инициализируется автоматически


В твоем примере strvar объявлен, как глобальный, значит, уже проинициализирован, это два.

Ты не используй сослагательного наклонения, ты пример приведи без извратов, чтобы подтвердить свою точку зрения из поста [5]


> если cтринговая переменная не проинициализирована, то инициализировать
> ее нужно pointer(strvar):=nil, strvar:='' можно словить
> av


oxffff   (2006-09-27 12:23:00) [63]

В [7] написано некорре
ктно
Строго говоря, инициализируется. Значением той переменной, которой присваивается возвращаемое ф-ей значение. По кр. мере так в D6.
Об этом говорит Sha ©.

Оно ничем не инициализируется. В данном случае возвращаемое значение это синоним Data.


zamtmn   (2006-09-27 12:15:00) [64]

>>Я не вижу неинициализированной strvar, первой же строкой из цикла ты ее "инициализируешь" в недопустимое значение.
Советую посмотреть CPU Window и понять, что так делать нельзя.
а ты увидь, если бы компилятор не позаботился о result, то result вполне бы указывал на недопустимое значение.
в делфи любой стринг локальный, глобальный инициализируется автоматически, неинициализированный стринг можно получить только создав его динамически.
>>Советую посмотреть CPU Window и понять, что так делать нельзя.
я какраз туда регулярно заглядываю, это вообщето был пример неинициализированного стринга


Игорь Шевченко   (2006-09-27 12:08:00) [65]

zamtmn ©   (27.09.06 12:04) [16]


> как сказано в [7] result:string автоматически инициализируемая
> переменная, иначе result:='' не прокатило бы


Ты прочитай [7] два раза вдумчиво. Пойми, где используется слово Result и почему оно инициализируется.


Игорь Шевченко   (2006-09-27 12:06:00) [66]

zamtmn ©   (27.09.06 11:54) [14]


>     for i:=1 to 100000 do
>     //будем перебирать варианты неинициализированной strvar
>     //хотя ошибку словим уже на первом:)
>     begin
>       pointer(strvar):=pointer(i);
>       strvar:='';
>     end;


Я не вижу неинициализированной strvar, первой же строкой из цикла ты ее "инициализируешь" в недопустимое значение.
Советую посмотреть CPU Window и понять, что так делать нельзя.


zamtmn   (2006-09-27 12:04:00) [67]

а что такого? эмуляция неинициализированности:)
как сказано в [7] result:string автоматически инициализируемая переменная, иначе result:='' не прокатило бы


ЮЮ   (2006-09-27 11:58:00) [68]

//будем перебирать варианты неинициализированной strvar
> pointer(strvar):=pointer(i);


Ничего себе "переборчик" :)


zamtmn   (2006-09-27 11:54:00) [69]

>>пример av в студию
program Project2;
{$APPTYPE CONSOLE}
uses
 SysUtils;
var strvar:string;
   i:Cardinal;
begin
    for i:=1 to 100000 do
    //будем перебирать варианты неинициализированной strvar
    //хотя ошибку словим уже на первом:)
    begin
      pointer(strvar):=pointer(i);
      strvar:='';
    end;
end.


oxffff   (2006-09-27 11:40:00) [70]

прошу прощения за опечатку естественно LEA, а не leax


oxffff   (2006-09-27 11:38:00) [71]

А что касаемо сабжа. Автору лучше посмотреть на asm и станет все понятно

register
leax eax,[data]
call GetSomeData

safecall
leax eax,[data]
call LstrClr
push eax
call GetSomeData
....


oxffff   (2006-09-27 11:32:00) [72]

Вам поможет safecall, который очищает result параметр перед вызовом.
Cмотрите oxffff ©   (27.09.06 11:25) [8]


Johnmen   (2006-09-27 11:31:00) [73]


> Игорь Шевченко ©   (27.09.06 11:29) [9]
> Johnmen ©   (27.09.06 11:24) [7] Вообще-то об этом говорит
> и Borland :)


Возможно. Только я Борланда не читаю...:))


Игорь Шевченко   (2006-09-27 11:29:00) [74]

Johnmen ©   (27.09.06 11:24) [7]

Вообще-то об этом говорит и Borland :)


oxffff   (2006-09-27 11:25:00) [75]

Сделай safecall. И будет тебе bla bla bla
function GetSomeData: string;safecall;
var i : integer;
begin
for i := 1 to 20 do
begin
  Result := Result + ' bla bla bla';
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Data : string;
begin
Data := 'some text';
Data := GetSomeData;
ShowMessage(Data);
end;


Johnmen   (2006-09-27 11:24:00) [76]


> Джо ©   (26.09.06 16:56) [2]
> Псевдо-переменная Result не инициализируется автоматически.


Строго говоря, инициализируется. Значением той переменной, которой присваивается возвращаемое ф-ей значение. По кр. мере так в D6.
Об этом говорит Sha ©.


Игорь Шевченко   (2006-09-27 11:18:00) [77]


> если cтринговая переменная не проинициализирована, то инициализировать
> ее нужно pointer(strvar):=nil, strvar:='' можно словить
> av


пример av в студию


zamtmn   (2006-09-27 10:58:00) [78]

>>Псевдо-переменная Result не инициализируется автоматически.
если cтринговая переменная не проинициализирована, то инициализировать ее нужно pointer(strvar):=nil, strvar:='' можно словить av


Пользователь   (2006-09-27 09:49:00) [79]

Стало быть этим можно пользоваться вместо параметров при вызове функции?

Чем вам не нравится использование параметров?

компилятор может какой-нибудь изврат придумать?

Если таким методом злоупотреблять, то, порой, компилятор начинает вписывать нецензурные слова. Правда, по-английски, но, все равно, перед пользователями неудобно...

Будет ли результат гарантирован?

Встреча с "восхищенными" пользователями вашей программы в темном корридоре без свидетелей - будет гарантирована точно. Но, при таком подходе к программированию, их (пользователей) будет немного. Так что, вероятно, вам удастся выжить.


Уч   (2006-09-27 05:21:00) [80]

Стало быть этим можно пользоваться вместо параметров при вызове функции? Будет ли результат гарантирован или компилятор может какой-нибудь изврат придумать?


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо