Я новичок в 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 истинны, а целые числа счисления - 2129993264, а неинициализированные объекты - это просто недопустимые указатели (т.е. не ноль). Я предполагаю, что норма должна всегда устанавливать переменные уровня процедуры перед их доступом?
Да, это документированное поведение:
Поля объекта всегда инициализируются 0, 0.0, '', False, ноль или что-то еще.
Глобальные переменные всегда инициализируются также 0 и т.д.
Локальные подсчетные переменные всегда инициализируются нулем или ';;
Локальные переменные, не содержащие ссылки, не инициализированы, поэтому вы должны назначить значение, прежде чем сможете их использовать.
Я помню, что Барри Келли где-то написал определение для "reference-counted", но больше не может его найти, поэтому это должно сделать в то же время:
reference-counted ==, которые подсчитываются сами по себе, или прямо или косвенно содержат поля (для записей) или элементы (для массивы), которые подсчитываются как:
string, variant, interface
или динамический массив или статический массив, содержащий такие типы.
Примечания:
record
сам по себе недостаточно, чтобы засчитыватьсяГлобальные переменные, не имеющие явного инициализатора, выделяются в разделе BSS в исполняемом файле. Они фактически не занимают места в EXE; раздел BSS - это специальный раздел, который ОС выделяет и очищает до нуля. В других операционных системах существуют аналогичные механизмы.
Вы можете зависеть от глобальных переменных, инициализированных нулями.
Поля класса по умолчанию равны нулю. Это документировано, поэтому вы можете положиться на него. Локальные varayables стека undefined, если строка или интерфейс не установлены равными нулю.
Как примечание к стороне (поскольку вы новичок в Delphi): глобальные переменные могут быть инициализированы непосредственно при их объявлении:
var myGlobal:integer=99;
Здесь цитата из Ray Lischners Delphi в двух словах Глава 2
"Когда Delphi сначала создает объект, все поля начинаются пустым, то есть указатели инициализируются на нуль, строки и динамические массивы пусты, числа имеют нулевое значение, логические поля - False, а варианты заданы к Неназначенному (подробности см. в NewInstance и InitInstance в Главе 5.)"
Верно, что переменные local-in-scope должны быть инициализированы... Я бы рассмотрел вышеприведенный комментарий, что "Глобальные переменные инициализируются" как сомнительные до тех пор, пока не будет предоставлена ссылка - я не верю в это.
редактировать... Барри Келли говорит, что вы можете полагаться на то, что они ноль-инициализированы, и поскольку он в команде разработчиков Delphi, я считаю, что стоит:) Спасибо Барри.
Из файла справки Delphi 2007:
мс-помощь://borland.bds5/devcommon/variables_xml.html
"Если вы явно не инициализируете глобальную переменную, компилятор инициализирует ее до 0.
Глобальные переменные и данные экземпляра объекта (поля) всегда инициализируются до нуля. Локальные переменные в процедурах и методах не инициализируются в Win32 Delphi; их содержание undefined, пока вы не присвоите им значение в коде.
У меня есть одна маленькая проблема с ответами. Delphi заносит в память пространство памяти глобалов и вновь созданных объектов. Хотя это NORMALLY означает, что они инициализированы, есть один случай, когда они не являются: перечислены типы со специфическими значениями. Что, если ноль не является юридическим значением?
Даже если язык предлагает инициализацию по умолчанию, я не верю, что вы должны полагаться на них. Инициализация значения делает его более понятным для других разработчиков, которые могут не знать о инициализации по умолчанию в языке и предотвращают проблемы между компиляторами.