The following code should compile and does compile with many other types.
However, the compiler reports a "Constant object cannot be passed as var parameter" error - despite the variable quite obviously being a variable.
program CurrencyConstant;
{$APPTYPE CONSOLE}
var
GVar: Currency;
begin
FillChar(GVar, SizeOf(GVar), 0);
end.
Similarly, the same problem occurs with a local variable in a procedure.
procedure TestCurrency;
var
LVar: Currency;
begin
FillChar(LVar, SizeOf(LVar), 0);
end;
I suspect it has something to do with the fact that FillChar
is a compiler magic procedure, and that Dest
is an untyped var parameter. FillChar
is the only routine I've found with this problem.
In response to the inevitable "Why would you do that comments": We have a code generator that uses FillChar to generically initialise record structures & primitive types. It works with everything else, but unexpectedly failed with Currency. We do have workarounds, but it would be nice to understand the root cause, and know whether anything else is likely to cause us trouble.
From Jeroen's answer it is reasonable to conclude that the issue exists in all vesions of Delphi. Furthermore array's of Currency apparently exhibit a similar problem.
David's answer provides some nice workarounds.
One final workaround to consider is, modifying the generator to deal with Currency as a special case and simply set the Value := 0
.
What causes the problem?
A compiler bug. Please submit a QC report.
Are any other types affected?
Maybe. Try some to find out.
As for a work around I would write it like this:
FillChar(Pointer(@LVar)^, SizeOf(LVar), 0);
or perhaps like this:
ZeroMemory(@LVar, SizeOf(LVar));
or even like this:
LVar := Default(Currency);
Personally I regard ZeroMemory
as being more descriptive than FillChar
.
As requested by Craig Young:
It still occurs in Delphi XE4.
Report No: 118866 Status: Reported
Cannot perform FillChar on Currency variables
https://web.archive.org/web/20150322021442/http://qc.embarcadero.com/wc/qcmain.aspx?d=118866
It is similar to http://qc.embarcadero.com/wc/qcmain.aspx?d=87168 (not archived)
The workaround for this compiler bug for Delphi < 2009: use ZeroMemory or FillMemory from the Windows unit which works just as well as FillChar.
On the Delphi side, ZeroMemory
and FillMemory
use FillChar
underneath which might be inlined as of Delphi 2006.
On the C++ side both use compiler macros.
It might be that this issue only happens with Currency
because that is the only numeric compiler type that is scaled.
The issue does not reproduce with ordinal types, regular floating point types, and Comp
.
Edit: The issue has been fixed in XE5 Update 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With