Я новичок в 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? Например, мне интересно, может ли это зависеть от настроек компилятора или, возможно, работать по-разному на разных машинах. Нормально ли полагаться на значения, инициализированные по умолчанию для объектов, или вы явно устанавливаете все переменные экземпляра в конструкторе?
Что касается переменных стека (уровня процедуры), мои тесты показывают, что унифицированные логические значения истинны, единичные целые числа - 2129993264, а неинициализированные объекты - это просто недопустимые указатели (т.е. не ноль). Я предполагаю, что нормой является всегда устанавливать переменные уровня процедуры перед доступом к ним?
Ответы:
Да, это задокументированное поведение:
Поля объекта всегда инициализируются значениями 0, 0.0, '', False, nil или любыми другими значениями.
Глобальные переменные также всегда инициализируются значением 0 и т. Д .;
Локальные переменные с подсчетом ссылок * всегда инициализируются значением nil или "";
Локальные переменные без подсчета ссылок * не инициализируются, поэтому вам необходимо присвоить значение, прежде чем вы сможете их использовать.
Я помню, что Барри Келли где-то написал определение для «подсчитываемых по ссылкам», но больше не могу его найти, так что пока что это нужно делать:
Ноты:
record
сам по себе недостаточно, чтобы стать подсчитываемымисточник
TObject.Create
, что является недействительным методом, но вclass function TObject.InitInstance(Instance: Pointer): TObject;
котором ВСЕГДА вызывается перед любым вызовом конструктора, даже для более старых версий Delphi. Ваш комментарий ИМХО неправильный и запутанный.Глобальные переменные, не имеющие явного инициализатора, размещаются в разделе BSS исполняемого файла. На самом деле они не занимают места в EXE; Раздел BSS - это специальный раздел, который ОС выделяет и очищает до нуля. В других операционных системах есть аналогичные механизмы.
Вы можете полагаться на то, что глобальные переменные инициализируются нулем.
источник
Поля класса по умолчанию равны нулю. Это задокументировано, так что вы можете на это положиться. Переменные локального стека не определены, если только строка или интерфейс не установлены в ноль.
источник
Также в качестве примечания (поскольку вы новичок в Delphi): глобальные переменные могут быть инициализированы непосредственно при их объявлении:
источник
Вот цитата из Рэя Лишнерса Delphi в двух словах, глава 2
Это правда, что локальные переменные в области видимости должны быть инициализированы ... Я бы рассматривал комментарий выше, что «Глобальные переменные инициализируются» как сомнительный, пока не будет предоставлена ссылка - я в это не верю.
edit ... Барри Келли говорит, что вы можете рассчитывать на то, что они инициализированы нулями, и, поскольку он работает в команде компиляторов Delphi, я считаю, что это так :) Спасибо, Барри.
источник
Глобальные переменные и данные экземпляра объекта (поля) всегда инициализируются нулем. Локальные переменные в процедурах и методах не инициализируются в Win32 Delphi; их содержание не определено, пока вы не присвоите им значение в коде.
источник
Даже если язык предлагает инициализацию по умолчанию, я не думаю, что вам следует на них полагаться. Инициализация со значением делает его намного более понятным для других разработчиков, которые могут не знать об инициализации по умолчанию на языке, и предотвращает проблемы между компиляторами.
источник
Из файла справки Delphi 2007:
ms-help: //borland.bds5/devcommon/variables_xml.html
источник
У меня есть одна небольшая претензия к полученным ответам. Delphi обнуляет пространство памяти глобальных переменных и вновь созданных объектов. Хотя это НОРМАЛЬНО означает, что они инициализированы, в одном случае это не так: перечислимые типы с определенными значениями. Что, если ноль не является допустимым значением?
источник
TOneTwoThree = (One=1, Two=2, Three=3);
Недавно введенные (начиная с Delphi 10.3) встроенные переменные упрощают управление начальными значениями.
источник