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

Reply via email to