Почему переменная Currency рассматривается как константа с FillChar в Delphi?
Следующий код должен компилироваться и компилироваться со многими другими типами.
Однако компилятор сообщает, что "Постоянный объект не может быть передан как параметр var parameter", несмотря на то, что переменная, очевидно, является переменной.
program CurrencyConstant;
{$APPTYPE CONSOLE}
var
GVar: Currency;
begin
FillChar(GVar, SizeOf(GVar), 0);
end.
Аналогично, та же проблема возникает с локальной переменной в процедуре.
procedure TestCurrency;
var
LVar: Currency;
begin
FillChar(LVar, SizeOf(LVar), 0);
end;
Я подозреваю, что это связано с тем, что FillChar
является магической процедурой компилятора и что Dest
является нетипизированным параметром var. FillChar
- единственная подпрограмма, которую я нашел с этой проблемой.
- Что вызывает эту проблему?
- Возникают ли какие-либо другие типы?
В ответ на неизбежное "Зачем вам делать эти комментарии": у нас есть генератор кода, который использует FillChar для генерации первичных структур записей и примитивных типов. Он работает со всем остальным, но неожиданно провалился с валютой. У нас есть обходные пути, но было бы неплохо понять первопричину и узнать, может ли что-то другое вызвать у нас проблемы.
Изменить
Из Jeroen answer разумно сделать вывод, что проблема существует во всех версиях Delphi. Кроме того, массив валют, по-видимому, имеет сходную проблему.
Ответ Дэвида дает некоторые полезные обходные пути.
Последнее решение, которое необходимо рассмотреть, - это изменение генератора для работы с валютой в качестве специального случая и просто установите Value := 0
.
Ответы
Ответ 1
Как запросил Craig Young:
Это все еще происходит в Delphi XE4.
№ отчета: 118866 Статус: Сообщено
Невозможно выполнить FillChar по валютным переменным
https://web.archive.org/web/20150322021442/http://qc.embarcadero.com/wc/qcmain.aspx?d=118866
Это похоже на http://qc.embarcadero.com/wc/qcmain.aspx?d=87168 (не архивировано)
Обходной путь для этой ошибки компилятора для Delphi < 2009: используйте ZeroMemory или FillMemory из блока Windows который работает так же хорошо, как FillChar.
На стороне Delphi ZeroMemory
и FillMemory
используйте FillChar
под которым может быть inlined с Delphi 2006. < ш > На стороне С++ оба используют макросы компилятора.
Возможно, эта проблема возникает только с Currency
, потому что это единственный тип числового компилятора, который масштабируется.
Проблема не воспроизводится с порядковыми типами, регулярными типами плавающих точек и Comp
.
Изменить: проблема исправлена в Обновление XE5 2
Ответ 2
Что вызывает проблему?
Ошибка компилятора. Пожалуйста, отправьте отчет о контроле качества.
Возникают ли какие-либо другие типы?
Может быть. Попробуйте узнать кое-что.
Что касается работы, я бы написал ее так:
FillChar(Pointer(@LVar)^, SizeOf(LVar), 0);
или, возможно, вот так:
ZeroMemory(@LVar, SizeOf(LVar));
или даже так:
LVar := Default(Currency);
Лично я считаю ZeroMemory
более описательным, чем FillChar
.