Инициализируются ли переменные Delphi значением по умолчанию?

StackOverflow https://stackoverflow.com/questions/132725

Вопрос

Я новичок в 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 обнуляет пространство памяти глобальных переменных и вновь созданных объектов.Хотя это ОБЫЧНО означает, что они инициализированы, есть один случай, когда это не так:перечислимые типы с конкретными значениями.Что, если ноль не является допустимым значением??

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top