[fpc-devel] About typecasts and the documentation
Hans-Peter Diettrich
DrDiettrich1 at aol.com
Sat Feb 8 22:59:51 CET 2014
Martin Frb schrieb:
> http://www.freepascal.org/docs-html/ref/refse67.html#x124-13400012.4
>> In general, the type size of the expression and the size of the type
>> cast must be the same. However, for ordinal types (byte, char, word,
>> boolean, enumerates) this is not so, they can be used interchangeably.
>> That is, the following will work, although the sizes do not match.
>
> http://www.freepascal.org/docs-html/ref/refse68.html#x125-13500012.5
>> A variable can be considered a single factor in an expression. It can
>> therefore be typecast as well. A variable can be typecast to any type,
>> provided the type has the same size as the original variable.
IMO type*cast* and type*conversion* should be kept separate. A cast then
requires that the *size* is the same, while in a conversion the *value*
stays the same. The compiler messages should reflect this difference
(see your example below).
Usually "typecast" can have both meanings, in detail for value
typecasts. Further terms are "type coercion", "type promotion".
Typecasts can be further restricted to *compatible* types. Here numeric
types seem to be compatible with other numeric types, but not with
structured types (records...). With classes sometimes a distinction
between upcast and downcast is made (type *inclusion*), where up and
down reflect more basic (ancestors) and more derived classes. Eventually
this also applies to conversions between Char and numeric types, for
which standard conversions Ord(c) and Chr(i) are defined.
It's not clear to me why a TStrings.Objects[i]:TObject can be compatible
with e.g. integer:
MyStringList.AddObject('1',TObject(1));
This may be due to some underlying implementation detail, where the list
(array) contains pointers instead of objects, and these pointers then
are compatible with numbers.
Often also multiple casts can be accepted, in something (untested) like
MyObject := TObject(pointer(1));
or
pointer(MyObject) := pointer(1);
IMO the detailed rules, as implemented in the compiler, are too complex
for a simple description. That's why the docs only explain the syntax,
not the full semantics behind the syntax.
> foo := TFoo(longint(1)); // project1.lpr(9,8) Error: Illegal type
> conversion: "LongInt" to "TFoo"
> foo := TFoo(1); // project1.lpr(10,8) Error: Illegal type conversion:
> "LongInt" to "TFoo"
> end.
Obviously the types (record and numeric) are considered incompatible by
the compiler.
DoDi
More information about the fpc-devel
mailing list