Is it possible to express an empty (zero) TDateTime value as a constant? I tried TDateTime(0)
, TDateTime(0.0)
and other things, but the compiler (Delphi 7) wasn't impressed.
At the moment I'm using an initialised global variable:
const
TDateTime_0: TDateTime = 0.0;
This sort of works. However, I just inherited a nice big pile of Delphi 7 code and I haven't used Turbo Pascal in ages... Which means I seriously need to brush up my Delphi fu, and this makes me want to know.
By contrast, the compiler is perfectly happy with something like Integer(0)
. Its assignment to a variant results in a value of 0 of type ftInteger
, whereas assigning a plain literal 0 would result in a variant of type ftSmallInt
.
Clarification: the objective is to pass an 'empty' value of a specific type to functions that take variants (which includes the compiler-managed variant arrays known as 'array of const' and also the setters for things like TParameter.Value).
Clarification for Ken White: the issue here is essentially type deduction and overload resolution; above-mentioned 'functions that take variants' are just a special case. The literals 0
and 0.0
are implicitly convertible to TDateTime
, which is why they can be assigned to receptacles of that type (variables, record fields) and they can be used to initialise such receptacles (i.e. function parameters) without further ado. However, things change when the compiler needs to do type deduction:
procedure foo (value: Double); overload;
procedure foo (value: TDateTime); overload;
The underlying type is Double in both cases, which means that the compiler requires arguments to be typed explicitly (i.e. calls with plain literals are rejected as ambiguous). With ordinal-based types the explicit typing is no problem but type Double is problematic and requires values to be stuffed into typed receptacles before they can be used. Compilable example (requires a Delphi that's a bit newer than Delphi 7):
type
TSomeId = type Integer;
procedure foo (value: Integer ); overload; begin WriteLn('Integer ', value); end;
procedure foo (value: TSomeId ); overload; begin WriteLn('TSomeId ', value); end;
procedure foo (value: Double ); overload; begin WriteLn('Double ', value); end;
procedure foo (value: TDateTime); overload; begin WriteLn('TDateTime ', value); end;
procedure test_TYPE_Double;
var
d: Double;
t: TDateTime;
begin
foo(Integer(0));
foo(TSomeId(0));
d := 0; foo(d);
t := 0; foo(t);
end;
My question is/was simply whether it is possible to form expressions of type TDateTime
(or other types based on Double
) in the same way as it is possible for Integer
and TSomeId
in the example above, without allocating and initialising a typed memory location for that purpose. However, Yuriy's answer indicates that this is only possible for ordinal types.
TDateTime
the same way thatInteger(0)
is of typeInteger
instead ofSmallInt
as a plain ('untyped') literal0
would be. I deliberately avoided the term 'typed constant` since Borland/Embarcadero lore uses that for read-only initialised variables, which is not the same thing. The exact type of an expression - constant or otherwise - is relevant in contexts where the compiler needs to do type deduction; assignment to (or initialisation of) variants is one such case, overload resolution is another. – DarthGizkatype x = TYPE y
construct that should make a totally unrelated type with no implicit typecasting. Kind of similar to my complain stackoverflow.com/questions/11029353 – Arioch 'TheAdvanced Records
+Operators Overloading
namelyimplicit type-cast
. If your record would have implicit inline typecasts to/from TDateTime but not to/from double than maybe - maybe - it could work. However Delphi 7 is far too old for those concepts. Dunno about FPC/Lazarus/CodeTyphon – Arioch 'The