
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.4] |
![]() |
|
Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Цитата ViktorXP @ Тут сказано что в каждой функции есть неявная локальная переменная result ... также получишь ошибку если попытаешься работать с не проинициализированой локальной переменной Это связано с тем что сам "компилятор" не чистит стек для локальных переменных и результата. ... это не касается массивов/строк/интерфейсов, "компилятор" их проинициализирует Не совсем так. Если заглянуть "под капот" Program Control -> Handling Function Results, то увидим, что результат функции "сложного" типа (к коим относятся статические массивы, записи и множества размером более 4 байт, а также managed типы строки\дин.массивы\варианты) передаются в функцию как дополнительный var-параметр. Поэтому в случае с возвратом строки компилятор не ругается на проверку Result не потому, что "локальная переменная" Result:string автоматически инициализируется нулем внутри функции, а потому, что в данном случае Result - это var-параметр, обязанность инициализации которого лежит на вызывающей стороне. Точно также компилятор не будет ругаться и в случае не managed-типа результата - записи, стат.массива или множества. Например: ![]() ![]() function Foo1:string; //по сути это procedure _Foo1(var Result:string); begin if Result = '' then Result:='empty string'; ShowMessage(Result); end; function Foo2:TPoint; //по сути это procedure _Foo2(var Result:TPoint); begin inc(Result.X); inc(Result.Y); ShowMessage(Format('%d; %d',[Result.X,Result.Y])); end; var s:string; P:TPoint; begin s:='Hello,World'; // s:=Foo1; //= _Foo1(s); P.X:=10; P.Y:=10; P:=Foo2; //= _Foo2(P); end; поскольку тут Foo1 и Foo2 по сути являются процедурами с var-параметрами, то компилятор НЕ ругается не только на отсутствие инициализации Result внутри этих функций, но также и на якобы неиспользуемые присваивания значений переменных s и P в вызывающей функции. Добавлено PS: Поэтому в общем случае, Result это не такая уж "обычная локальная переменная", как следует из ее "высокоуровневого" описания. В частности, присваивание Result "сразу, без использования дополнительной переменной" может приводить к различному поведению\результату в случае необработанного исключения в функции - для типов Result, возвращаемых через регистры, значение переменной, которой присваивается значение функции, в случае ошибки не изменится, а для типов, передаваемых через var-параметр оно меняется "сразу" и соотв-но будет содержать значение Result на момент возникновения исключения. |
![]() |
Сообщ.
#17
,
|
|
Это уже особенности реализации компилятора. Которые не опровергают существования result как локальной переменной, но накладывает небольшие условия.
пс. но странно будет сотрется код в котором при исключении я не буду корректировать возвращаемый результат или иными способами обрабатывать это исключение. |