Инициализируются ли переменные Delphi значением по умолчанию?
-
02-07-2019 - |
Вопрос
Я новичок в 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 или '';
Локальные переменные без подсчета ссылок* не инициализированы, поэтому вам необходимо присвоить значение, прежде чем вы сможете их использовать.
я помню это Барри Келли где-то написал определение «с подсчетом ссылок», но больше не могу его найти, так что пока это следует сделать:
Ссылка на ссылку ==, которые сами находятся на ссылке, или прямо или косвенно содержат поля (для записей) или элементы (для массивов), которые привязаны к ссылке, как:
string, variant, interface
или динамический массив или статический массив содержащие такие типы.
Примечания:
record
самого по себе недостаточно, чтобы стать подсчитываемым ссылками- Я еще не пробовал это с дженериками
Другие советы
Глобальные переменные, не имеющие явного инициализатора, размещаются в разделе BSS исполняемого файла.На самом деле они не занимают места в EXE;раздел BSS — это специальный раздел, который ОС выделяет и очищает до нуля.В других операционных системах существуют аналогичные механизмы.
Вы можете быть уверены в том, что глобальные переменные инициализируются нулями.
Поля класса по умолчанию равны нулю.Это задокументировано, поэтому вы можете на это положиться.Переменные локального стека не определены, если только строка или интерфейс не установлены в ноль.
В качестве примечания (поскольку вы новичок в Delphi):Глобальные переменные могут быть инициализированы непосредственно при их объявлении:
var myGlobal:integer=99;
Вот цитата Рэя Лишнера: «Кратко о Delphi» Глава 2
«Когда Delphi впервые создает объект, все поля начинаются пустыми, то есть указатели инициализируются нулевым значением, строки и динамические массивы пусты, числа имеют нулевое значение, логические поля имеют значение False, а варианты устанавливаются в значение «Не назначено».(Подробнее см. в разделах NewInstance и InitInstance в главе 5.)»
Это правда, что локальные переменные необходимо инициализировать...Я бы отнесся к комментарию выше о том, что «глобальные переменные инициализируются», как сомнительному, пока не будет предоставлена ссылка - я в это не верю.
редактировать...Барри Келли говорит, что вы можете быть уверены в том, что они будут инициализированы нулями, и, поскольку он входит в команду компиляторов Delphi, я считаю, что это правда :) Спасибо, Барри.
Глобальные переменные и данные экземпляра объекта (поля) всегда инициализируются нулем.Локальные переменные в процедурах и методах не инициализируются в Win32 Delphi;их содержимое не определено, пока вы не присвоите им значение в коде.
Даже если язык предлагает инициализацию по умолчанию, я не считаю, что вам следует на них полагаться.Инициализация значения делает его более понятным для других разработчиков, которые могут не знать об инициализации по умолчанию в языке, и предотвращает проблемы в компиляторах.
Из файла справки Delphi 2007:
ms-help://borland.bds5/devcommon/variables_xml.html
«Если вы явно не инициализируете глобальную переменную, компилятор инициализирует ее значением 0».
У меня есть одно небольшое недовольство полученными ответами.Delphi обнуляет пространство памяти глобальных переменных и вновь созданных объектов.Хотя это ОБЫЧНО означает, что они инициализированы, есть один случай, когда это не так:перечислимые типы с конкретными значениями.Что, если ноль не является допустимым значением??