User Tools

Site Tools


casting

Casting

Casting is a very dangerous technique, specially when it comes to the 64 bit mode.

There are functions that return an int value, but this value in reality is a pointer that points to a structure or an object or some other memory construct. This perfectly legal (but also dangerous) in a 32 bit world, but wrong in a 64 bit world where pointers are not more occupying 32 bit, but 64 bit.

So if you are migrating code from VO to X#, please check all your casts. The following code, permitted in VO:

local i := 67 as int
local o1 as object
local o2 as object
o1 := (object) i
o2 := object( _cast, i )

will compile in Vulcan.NET, but not in X#. The first assignment will compile and work in X#, because the compiler knows the type of both variables and inserts a conversion method - so this code is safe. The second assignment will not compile in X# because it cannot work in a .NET world - it is simply not admitted. A member of the development team stated: For this reason, we intentionally disallowed that specific syntax (OBJECT(_CAST, i)) in order to trap some problems in compile time and not at runtime later. This refers to the second assignment (with the _cast), but not to the first, as it is legal code.

In VO, sometimes casts are used as follows:

local p as ptr
local oWindow as DataWindow
...
p := @oWindow

and then p is is assigned to an int

local n as int
n := p

The variable n is then used in several ways, like sorts, callbacks, in parameters, etc. To access the object again, n is casted to the object:

oWindow := object( _cast, n )

This works in VO, until the object has not moved by the garbage collector. When the garbage collector has moved the object, the pointer and the int variable still point to a (maybe valid) memory location, but not to the original object. Therefore this is very dangerous also in VO. In .NET such pointers are not allowed, therefore the development team has disallowed the compilation of such code. The only valid representation of an object by a numeric variable is when the numeric is an index to an array of objects, and it remains valid also when the garbage collector kicks in. But this type of valid code is rarely seen in VO code. And the .NET Framework has another possibility to map an object to a numeric variable: the System.Runtime.Interopservices.GCHandle structure. Please see this page for more details: GCHandle: cast an object to a number

Please see the entire thread about it in the X# forum: www.xsharp.info/forum/public-product/832-2-0-0-2-cannot-cast-type-int-to-object, specially the last two messages.

casting.txt · Last modified: 2018/09/07 04:04 by wolfgangriedmann