Переменные delphi инициализируются значением по умолчанию? - PullRequest
94 голосов
/ 25 сентября 2008

Я новичок в 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 ]

99 голосов
/ 25 сентября 2008

Да, это задокументированное поведение:

  • Поля объекта всегда инициализируются равными 0, 0.0, '', False, nil или любым другим.

  • Глобальные переменные всегда также обнуляются и т. Д .;

  • Локальные переменные с подсчетом ссылок * всегда инициализируются как ноль или '';

  • Локальные переменные без учета ссылок неинициализированы, поэтому вам необходимо присвоить значение, прежде чем вы сможете их использовать.

Я помню, что Барри Келли где-то написал определение для "подсчитанных ссылок", но больше не может его найти, так что это должно быть тем временем:

подсчитанные ссылки ==, которые сами подсчитывают ссылки, или прямо или косвенно содержать поля (для записей) или элементы (для массивы), которые подсчитываются как: string, variant, interface или динамический массив или статический массив , содержащий такие типы.

Примечания:

  • record само по себе недостаточно для подсчета ссылок
  • Я еще не пробовал это с дженериками
26 голосов
/ 25 сентября 2008

Глобальные переменные, которые не имеют явного инициализатора, размещаются в разделе BSS исполняемого файла. Они на самом деле не занимают места в EXE; раздел BSS - это специальный раздел, который ОС выделяет и очищает до нуля. В других операционных системах существуют аналогичные механизмы.

Вы можете зависеть от инициализации нуля глобальных переменных.

20 голосов
/ 25 сентября 2008

Поля класса по умолчанию равны нулю. Это задокументировано, так что вы можете положиться на него. Переменные локального стека не определены, если только строка или интерфейс не установлены в ноль.

16 голосов
/ 30 января 2009

Как примечание (поскольку вы новичок в Delphi): Глобальные переменные могут быть инициализированы непосредственно при их объявлении:

var myGlobal:integer=99;
8 голосов
/ 25 сентября 2008

Вот цитата Рэя Лишнерса Delphi в двух словах Глава 2

"Когда Delphi впервые создает объект, все поля начинаются пустыми, то есть указатели инициализируются равными nil, строки и динамические массивы пусты, числа имеют значение ноль, логические поля - False, и устанавливаются варианты на Unassigned. (Подробнее см. NewInstance и InitInstance в Главе 5.) "

Это правда, что локальные переменные в области видимости должны быть инициализированы ... Я бы трактовал приведенный выше комментарий о том, что "Глобальные переменные инициализируются", как сомнительный, пока не будет предоставлена ​​ссылка - я не верю этому. *

редактировать ... Барри Келли говорит, что вы можете зависеть от того, что они инициализируются нулями, и, поскольку он работает в команде компиляторов Delphi, я верю, что это так :) Спасибо, Барри.

6 голосов
/ 25 сентября 2008

Глобальные переменные и данные экземпляра объекта (поля) всегда обнуляются. Локальные переменные в процедурах и методах не инициализируются в Win32 Delphi; их содержимое не определено, пока вы не назначите им значение в коде.

4 голосов
/ 25 сентября 2008

Из справочного файла Delphi 2007:

мс-помощь: //borland.bds5/devcommon/variables_xml.html

"Если вы не инициализируете глобальную переменную явно, компилятор инициализирует ее как 0."

4 голосов
/ 25 сентября 2008

Даже если язык действительно предлагает инициализации по умолчанию, я не думаю, что вы должны полагаться на них. Инициализация значения делает его намного более понятным для других разработчиков, которые могут не знать об инициализации по умолчанию в языке, и предотвращает проблемы между компиляторами.

3 голосов
/ 25 сентября 2008

У меня есть одна маленькая хватка с данными ответами. Delphi обнуляет пространство памяти глобалов и вновь созданных объектов. Хотя это НОРМАЛЬНО означает, что они инициализированы, есть один случай, когда они не являются: перечислимые типы с конкретными значениями. Что если ноль не является допустимым значением?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...