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
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel