To cast or not to cast

This forum is meant for questions and discussions about the X# language and tools
Post Reply
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

To cast or not to cast

Post by wriedmann »

Hi Robert,

I think a forum message is better suited to answer to your post.

I have done now a search in my largest VO project for all occurrences of _cast and found only 1.649 of them <g>.
Most of them are in the VO Class libraries code and in the bBrowser, and the others in code to enhances ListViews or interface to MAPI, and some of them adress the return value of PCALL().

Personally, I would mark all casts with usuals as errors, so we should look at them and correct the code.
IMHO it is better to fix code than to have some code that don't works and we don't know why.
Casts to typed values, and specially to value types are relatively safe. Casts to typed reference values are to check because in .NET they could give undesired (or wrong) results.

These are a few samples how _cast is used in my code:

Code: Select all

MAPILogon( dword( _cast, HWND_DESKTOP ), null_ptr, null_ptr, 0, 0, @nSession )

Code: Select all

sMAPI.pFreeBuffer    := GetProcAddress( hLib , PSZ( _CAST , "MAPIFreeBuffer" ) )

Code: Select all

MemFree( PTR ( _CAST, pszCaption ) )

Code: Select all

SendMessage( self:Handle(), CB_GETITEMHEIGHT, Word( _Cast, -1 ), 20 )

Code: Select all

ListView_SetItem(hHandle, LONG(_CAST, strucItem))
Much of this code is very old, and often taken from other sources, but in VO applications it works for many years now.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

To cast or not to cast

Post by wriedmann »

Hi Robert,

another thing: casting to pointers in legacy 32 bit code may be ok, but will not be ok in a 64 bit world.

Therefore I would change the compiler behavior dependent on the compiler mode: ok for x86, compiler error for x64 or AnyCPU.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4562
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

To cast or not to cast

Post by Chris »

I like the idea of throwing an error on using _CAST with USUALs. But maybe not with integer numeric types (and LOGIC probably), because there's probably a lot of existing code that uses that and it is safe to use it in VO, so in order to make it easier to directly port code, I think it's better to allow it.

In any case, all <integer type>(_CAST, uUsual) conversions (because they are not really casts in .Net) do already work in X# in a VO compatible way, except for SHORTINT. I think it's better to make SHORTINT work, too, and report a warning about those conversions that they will not work in other platforms (although it is not very likely to run a VO ported app in a different platform :))

And maybe throw an error for any other type, like FLOAT, STRING etc.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am

To cast or not to cast

Post by Karl-Heinz »

I would vote for a warning if the compiler detects _cast problems, similar like he already does in this case:

PTR( _CAST , cText )

warning XS9068: The compiler generated an automatic conversion to PSZ. This may create a memory leak in your application. Please use String2Psz() to let the compiler manage the lifetime of the PSZ or use StringAlloc() and manage the lifetime of the PSZ yourself.

regards
Karl-Heinz
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am

To cast or not to cast

Post by Karl-Heinz »

Inspired by this thread I´ve looked at the integer() function. I've noticed that Integer() returns negative numbers as soon the integer is greater than int32.maxvalue. But this happens also if such integers are assigned to usuals or floats.

All VO results are as expected:

LOCAL u AS USUAL
LOCAL f AS FLOAT

u := Integer ( 2147483647 + 1 )
f := Integer ( 2147483647 + 1 )
? u // 2147483648
? f // 2147483648
?
u := Integer ( 2147483647.00 + 1 )
f := Integer ( 2147483647.00 + 1 )
? u // 2147483648
? f // 2147483648
?
u := 2147483647 + 1
f := 2147483647 + 1
? u // 2147483648
? f // 2147483648
?
u := 2147483647.00 + 1
f := 2147483647.00 + 1
? u // 2147483648,00
? f // 2147483648,00
?

X# results:
-------------

Code: Select all


LOCAL u AS USUAL                     
LOCAL f AS FLOAT
LOCAL iNum AS INT 

  iNum := 1  
  
  // 2147483647 == max int  
  
 
  u := integer ( 2147483647 + iNum ) //integer
  f := integer ( 2147483647 + iNum ) //integer
 
  ? u  // -2147483648   iNum = 1
  ? f  // -2147483648   iNum = 1
  ?
  
  u := integer ( 2147483647d + iNum )  // float
  f := integer ( 2147483647d + iNum )  // float
  
  ? u  // 2147483648   iNum = 1  ok
  ? f  // 2147483648   iNum = 1  ok
  ? 

   u := 2147483647 + iNum    //integer
   f := 2147483647 + iNum    //integer

   ? u  // -2147483648   iNum = 1
   ? f  // -2147483648   iNum = 1
   ?
   
   u := 2147483647d + iNum  // float
   f := 2147483647d + iNum  // float
   
   ? u  // 2147483648,00   iNum = 1   ok
   ? f  // 2147483648,00   iNum = 1   ok    
   ?

regards
Karl-Heinz
User avatar
Chris
Posts: 4562
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

To cast or not to cast

Post by Chris »

Hi Karl-Heinz,

Sorry for the delay and thanks for the report, problem confirmed and logged!

Does not seem related to the Integer() function, though, but it's a compiler problem treating the expression "2147483647 + 1" as an int (which overflows), instead of using a larger numeric type before assigning it to the USUAL or FLOAT var, Robert will look into it.

Chris
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Post Reply