Переменные delphi инициализируются значением по умолчанию?
Я новичок в Delphi, и я провел несколько тестов, чтобы увидеть, какие переменные объекта и переменные стека по умолчанию инициализируются:
TInstanceVariables = class
fBoolean: boolean; // always starts off as false
fInteger: integer; // always starts off as zero
fObject: TObject; // always starts off as nil
end;
Это поведение, к которому я привык из других языков, но мне интересно, безопасно ли на него полагаться в Delphi? Например, мне интересно, может ли это зависеть от настроек компилятора или работать по-разному на разных машинах. Нормально ли полагаться на инициализированные значения по умолчанию для объектов, или вы явно устанавливаете все переменные экземпляра в конструкторе?
Что касается переменных стека (на уровне процедуры), мои тесты показывают, что унифицированные логические значения имеют значение true, целочисленные целочисленные значения равны 2129993264, а неинициализированные объекты являются просто недопустимыми указателями (т. Е. Не nil). Я предполагаю, что норма состоит в том, чтобы всегда устанавливать переменные уровня процедуры, прежде чем получить к ним доступ?
9 ответов
Да, это документированное поведение:
Поля объекта всегда инициализируются в 0, 0.0, '', False, nil или что-либо другое.
Глобальные переменные всегда также обнуляются и т. Д.;
Локальные переменные с подсчетом ссылок * всегда инициализируются как nil или '';
Локальные переменные без подсчета ссылок неинициализированы, поэтому вам необходимо присвоить значение, прежде чем вы сможете их использовать.
Я помню, что Barry Kelly где-то написал определение для "подсчитанных ссылок", но больше не может его найти, так что это должно быть сделано в это время:
подсчитанные ссылки ==, которые сами подсчитывают ссылки, или прямо или косвенно содержат поля (для записей) или элементы (для массивов), которые подсчитываются как:
string, variant, interface
или динамический массив или статический массив, содержащий такие типы.
Заметки:
record
само по себе недостаточно, чтобы стать подсчитываемым- Я еще не пробовал это с дженериками
Глобальные переменные, которые не имеют явного инициализатора, размещаются в разделе BSS исполняемого файла. Они на самом деле не занимают места в EXE; раздел BSS - это специальный раздел, который ОС выделяет и очищает до нуля. В других операционных системах существуют аналогичные механизмы.
Вы можете зависеть от инициализации нуля глобальных переменных.
Поля класса по умолчанию нулевые. Это задокументировано, так что вы можете положиться на него. Переменные локального стека не определены, если только строка или интерфейс не установлены в ноль.
Как примечание (как вы новичок в Delphi): Глобальные переменные могут быть инициализированы непосредственно при их объявлении:
var myGlobal:integer=99;
Вот цитата из Рэя Лишнерса Дельфи в двух словах. Глава 2
"Когда Delphi впервые создает объект, все поля начинаются пустыми, то есть указатели инициализируются равными nil, строки и динамические массивы пусты, числа имеют значение ноль, логические поля - False, а варианты - Unassigned. (Подробнее см. NewInstance и InitInstance в главе 5.)"
Это правда, что локальные переменные в области видимости должны быть инициализированы... Я бы рассматривал приведенный выше комментарий о том, что "Глобальные переменные инициализируются", как сомнительный, пока не будет предоставлена ссылка - я не верю в это.
редактировать... Барри Келли говорит, что вы можете зависеть от того, что они инициализируются нулями, и, поскольку он работает в команде компиляторов Delphi, я верю, что это так:) Спасибо, Барри.
Глобальные переменные и данные экземпляра объекта (поля) всегда обнуляются. Локальные переменные в процедурах и методах не инициализируются в Win32 Delphi; их содержание не определено, пока вы не назначите им значение в коде.
Даже если язык действительно предлагает инициализации по умолчанию, я не верю, что вы должны полагаться на них. Инициализация значения делает его намного более понятным для других разработчиков, которые могут не знать об инициализации по умолчанию в языке, и предотвращает проблемы между компиляторами.
У меня есть одна маленькая хватка с ответами, данными. Delphi обнуляет пространство памяти глобалов и вновь созданных объектов. Хотя это НОРМАЛЬНО означает, что они инициализируются, есть один случай, когда они не инициализируются: перечислимые типы с конкретными значениями. Что если ноль не является допустимым значением??
Из справочного файла Delphi 2007:
мс-помощь: //borland.bds5/devcommon/variables_xml.html
"Если вы явно не инициализируете глобальную переменную, компилятор инициализирует ее как 0."
Недавно представленные (начиная с Delphi 10.3) встроенные переменные упрощают управление начальными значениями.
procedure TestInlineVariable;
begin
var index: Integer := 345;
ShowMessage(index.ToString);
end;