Почему переменная 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.