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

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

Чтобы локальные переменные в функциях


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

Бездомный ©   (2011-10-06 13:35:00) 

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

Если нет, можно ли как-нибудь написать такую процедурку LocalNullify:

function foo (param1, param2, ... paramN: AnyType1, ...): AnyType;
var
 ... тут неопределенное количество переменных, неопределенного размера ...
begin
 LocalNullify;
 //-- все локальные переменные обнулились, можно работать.
end;


Компилятор же некоторые типы (интерфейсы, динамические массивы) все-таки инициализирует.

P.S. Delphi 7, Delphi XE,XE2


Дмитрий Белькевич   (2011-10-06 21:15:00) [21]

>Вместо кучи локальных переменных делаем объект

Читать: Вместо кучи локальных переменных делаем класс.


Дмитрий Белькевич   (2011-10-06 21:13:00) [22]


> Чтобы не писать:Errors := nil;Output:= nil;ProgressForm
> := nil;Query:=nil;


Вместо кучи локальных переменных делаем объект, который содержит Errors, Output, ProgressForm, Query. Создаем локально экземпляр этого объекта и в finally его разрушаем. Это если локальные переменные - инстансы классов.

Дальше. Если локальные - нединамические. Вместо кучи локальных переменных делаем запись, содержащую список этих переменных. Делаем записи ZeroMemory - при этом она вся очистится, не зависимо от того, сколько в ней реально переменных содержится.

Как-то так...


Ega23   (2011-10-06 20:36:00) [23]


> Вообще, какой смысл в "заниливание" ты вкладываешь?


var
 fs: TFileStream;
begin
try
 fs := nil;
 try
   fs := TFileStream.Create('', fmCreate);
 finally
   fs.Free;
 end;
except
end;
end;


Правда вот нафига такой код нужен?


Ega23   (2011-10-06 20:31:00) [24]


> А подумать?


и если подумать, то ничего страшного не будет.


Dennis I. Komarov   (2011-10-06 20:31:00) [25]

Вообще, какой смысл в "заниливание" ты вкладываешь?


Dennis I. Komarov   (2011-10-06 20:29:00) [26]


> Ничего страшного не будет, если выполнить
> var Object: TObject;
> begin
>  Object := nil;
>  Object.Free;
> end;

А подумать?


Ega23   (2011-10-06 19:31:00) [27]


> Что-бы меньше писать.


Ищи золотую середину.
Полное отсутствие декомпозиции - крайне неудобная и вредная вещь.
Бездумная декомпозиция всего и вся - тоже крайне неудобная и вредная вещь.


_Юрий   (2011-10-06 18:56:00) [28]


>  localVar2:= List.AddEx(TClass3.Create);


localVar 3:= List.AddEx(TClass3.Create);


_Юрий   (2011-10-06 18:55:00) [29]

Можно запихать все в обжект-лист. Предварительно объявив хелпер к нему для удобства:

type
 TObjectListHelper = class helper for  TObjectList
 public
   function AddEx(Obj: TObject): Pointer;//добавить Obj и вернуть его же

List:=TObjectList.Create();
try
 localVar1:= List.AddEx(TClass1.Create);
 localVar2:= List.AddEx(TClass2.Create);
 localVar2:= List.AddEx(TClass3.Create);
...
finally
 List.Free;
end;

теперь, если исключение произошло в одном из конструкторов, этот экземпляр автоматически разрушится и не добавится в лист, ранее добавленные гарантированно разрушатся на файналли


Бездомный   (2011-10-06 18:22:00) [30]


> Ega23 ©   (06.10.11 17:41) [26]

Ничего страшного не будет, если выполнить
var Object: TObject;
begin
 Object := nil;
 Object.Free;
end;


> Присоединяюсь к предыдущим ораторам - а нафиг ?

Что-бы меньше писать.


> стоит подумать об их композиции в класс.

Согласен.


Игорь Шевченко   (2011-10-06 18:11:00) [31]


> Речь идет о создании нескольких объектов сразу


Присоединяюсь к предыдущим ораторам - а нафиг ? если они все обязаны быть созданными для выполнения работы, стоит подумать об их композиции в класс.


Ega23   (2011-10-06 17:41:00) [32]


> В этом варианте я вижу AV только в случае если какой-то
> из объектов поднимет исключение при освобождении.


Ну правильно, он у тебя ещё не создан, указатель на него может быть nil, а может и нет (что скорее всего), а ты ему Free пытаешься сделать.


oxffff   (2011-10-06 17:34:00) [33]

У меня по рукой сейчас только SAP и ABAP. ;)
Delphi после работы.


oxffff   (2011-10-06 17:33:00) [34]


> Самый простой способ запихать все в record и чистить ее
> как угодно.
> также и финализатор к ней написать универсальный без необходимости
> каскадного finally ручками.


Для record поставить align sizeof(pointer) и далее в цикле по полям с try except
и далее по списку если что надо дополнительно.


oxffff   (2011-10-06 17:30:00) [35]

Можно написать процедуру которая чистит от esp до ebp.
Но это не всегда будет безопасно, поскольку для анонимных методов например
создается временный объект, который можно таким образом затереть.

Самый простой способ запихать все в record и чистить ее как угодно.
также и финализатор к ней написать универсальный без необходимости каскадного finally ручками.


Ega23   (2011-10-06 17:29:00) [36]

Так. Я малость напутал. Даже не малость.
Спутал с конструктором и деструктором и созданием-удалением локальных полей-объектов.


Бездомный   (2011-10-06 17:19:00) [37]

В этом варианте я вижу AV только в случае если какой-то из объектов поднимет исключение при освобождении.


Бездомный   (2011-10-06 17:18:00) [38]

Вот это уже конструктивно, спасибо.

Если не затруднить объясните это:


> 2. Тут особых проблем не наблюдается, но нужна поддержка
> кода, т.к. уничтожать объекты нужно строго в обратном порядке,
>  иначе чревато либо AV, либо мемликом, а в целом - и тем
> и другим одновременно.


Ega23   (2011-10-06 16:37:00) [39]


> Спасибо, ваше сообщение очень помогло разобраться в теме
> вопроса, не даром о вас слава ходит.


В данном случае сарказм не уместен.
Вы хотите "странного". Образно говоря, вы хотите заполучить асфальтовый каток, для того чтобы смело ездить по граблям, вместо того, чтобы просто по ним не ходить.
Никто не мешает и не запрещает:
1. создавать объекты внутри try.
2. не оборачивать каждый объект try..finally, а сделать его одним.
3. накатать простыню, как в [15].
4. создать стопицот локальных объектов в рамках одной процедуры.
По пунктам:
1. Создание объекта внутри try чревато Вашей проблемой.
2. Тут особых проблем не наблюдается, но нужна поддержка кода, т.к. уничтожать объекты нужно строго в обратном порядке, иначе чревато либо AV, либо мемликом, а в целом - и тем и другим одновременно.
3. Можно, но когда объектов дофига - довольно безобразная простыня получается.
4. Интереса ради, загляните в код VCL. Я вот наугад открыл Forms.pas, довольно большое количество локальных переменных увидел только в TCustomForm.WndProc (ну это и понятно).

Да, и у меня бывает по 6-8 локальных объектов. Особенно, когда какой-то тестик надо очень по-быстрому накатать. Но если это в "продакшн" идёт, то имеет смысл эти объекты с их логикой взаимодействия куда-то спрятать.


Бездомный   (2011-10-06 16:08:00) [40]


> Ega23 ©   (06.10.11 14:28) [16]

Спасибо, ваше сообщение очень помогло разобраться в теме вопроса, не даром о вас слава ходит.


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

Наверх

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