Переменные Делфи инициализируется со значением по умолчанию?



Я новичок в 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? Например, мне интересно, может ли это зависеть от настроек компилятора или, возможно, работать по-разному на разных машинах. Нормально ли полагаться на инициализированные значения по умолчанию для объектов или вы явно устанавливаете все переменные экземпляра в конструкторе?



что касается переменных стека (на уровне процедуры), мои тесты показывают, что unitialized booleans истинны, unitialized integers-2129993264, а неинициализированные объекты-это просто недопустимые указатели (т. е. не nil). Я предполагаю, что норма заключается в том, чтобы всегда устанавливать переменные уровня процедуры перед их доступом?

1011   9  

9 ответов:

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

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

  • глобальные переменные всегда инициализируются в 0 и т. д.;

  • Local reference-counted * переменные всегда инициализируются до нуля или ";

  • Local non reference-counted * переменные неинициализированы, поэтому вам нужно назначить значение, прежде чем вы сможете использовать их.

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

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

Примечания:

  • record сам по себе недостаточно, чтобы стать ссылочным подсчетом
  • я еще не пробовал это с дженериками

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

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

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

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

var myGlobal:integer=99;

вот цитата из Ray Lischners Delphi в двух словах Глава 2

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

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

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

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

из файла справки Delphi 2007:

ms-help: / / borland.bds5 / devcommon / variables_xml.HTML-код

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

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

У меня есть одна небольшая проблема с ответами. Delphi обнуляет пространство памяти глобалов и вновь созданных объектов. Пока это нормально означает, что они инициализированы есть один случай, когда они не являются: перечислимые типы с определенными значениями. Что делать, если ноль не является юридическим значением??

Comments

    Ничего не найдено.