Author Topic: Casting off.....  (Read 1700 times)

airr

  • Sr. Member
  • ****
  • Posts: 252
    • View Profile
Casting off.....
« on: May 15, 2024, 06:19:33 PM »
Any thought on why CAST doesn't seem to work as I thought it would?

OUTPUT:
Code: [Select]
PS C:\Users\ar4024\Projects\bcx> .\convert_filesize.exe
 801264801 bytes is equal to 782485.157226563 KB
 801264801 bytes is equal to 3.86598956886088E-318 KB

Press any key to continue . . .

Code I'm Using:
Code: [Select]
dim as int a = 801264801

dim as double kb, kb2, tmp

kb = (double)a / (1 shl 10)
kb2 = cast(double, a) / (1 shl 10)


print a," bytes is equal to", kb," KB"
print a," bytes is equal to", kb2," KB"

pause

AIR.

Robert

  • Hero Member
  • *****
  • Posts: 1256
    • View Profile
Re: Casting off.....
« Reply #1 on: May 15, 2024, 08:30:48 PM »
Compiling "E:\t\temp.cpp" with Nuwen g++.exe
E:\t\temp.cpp: In function 'int main(int, char**)':
E:\t\temp.cpp:176:34: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
  176 | #define CAST(to_type,old_obj) (*((to_type*)(&(old_obj))))
      |                                 ~^~~~~~~~~~~~~~~~~~~~~~~
E:\t\temp.cpp:202:8: note: in expansion of macro 'CAST'
  202 |   kb2= CAST (double,a)/(1<<10);
      |        ^~~~
E:\t\temp.cpp:199:14: warning: unused parameter 'argc' [-Wunused-parameter]
  199 | int main(int argc, char *argv[])
      |          ~~~~^~~~
E:\t\temp.cpp:199:26: warning: unused parameter 'argv' [-Wunused-parameter]
  199 | int main(int argc, char *argv[])
      |                    ~~~~~~^~~~~~
E:\t\temp.cpp: At global scope:
E:\t\temp.cpp:169:16: warning: 'tmp' defined but not used [-Wunused-variable]
  169 | static double  tmp;
      |                ^~~
E:\t\temp.cpp: In function 'int main(int, char**)':
E:\t\temp.cpp:176:32: warning: array subscript 'double[0]' is partly outside array bounds of 'int [1]' [-Warray-bounds=]
  176 | #define CAST(to_type,old_obj) (*((to_type*)(&(old_obj))))
      |                               ~^~~~~~~~~~~~~~~~~~~~~~~~~~
E:\t\temp.cpp:202:8: note: in expansion of macro 'CAST'
  202 |   kb2= CAST (double,a)/(1<<10);
      |        ^~~~
E:\t\temp.cpp:170:16: note: object 'a' of size 4
  170 | static int     a=801264801;
      |                ^
Finished!

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2392
    • View Profile
Re: Casting off.....
« Reply #2 on: May 15, 2024, 08:31:40 PM »
BCX uses the CAST macro created a couple of decades ago by Jerry Coffin and which was
found in the old but popular C Snippets Collection on snippets.org.  Fun fact, Wayne Halsdorf
was one of the contributor to snippets.  Snippets.org can be found on the Wayback Machine
here:  https://web.archive.org/web/20071218111608/http://c.snippets.org/

But here's the thing ... If I use my simpler KAST macro (below), your example works.  I don't know
what I'll break if I change the BCX CAST macro to this but there's one way to find out.  Opinions?
Perhaps my simpler cast was not possible with earlier C compilers?  Just a hunch ...

MACRO KAST(to_type, old_obj) = ((to_type)(old_obj))


DIM AS INT a = 801264801

DIM AS DOUBLE kb, kb2

kb = ((DOUBLE)a) / (1 shl 10)
kb2 =  KAST(DOUBLE, a) / (1 shl 10)


PRINT a, " bytes is equal to", kb, " KB"
PRINT a, " bytes is equal to", kb2, " KB"

PAUSE

« Last Edit: May 15, 2024, 09:33:32 PM by MrBcx »

airr

  • Sr. Member
  • ****
  • Posts: 252
    • View Profile
Re: Casting off.....
« Reply #3 on: May 15, 2024, 10:14:36 PM »
I don't know what I'll break if I change the BCX CAST macro to this but there's one way to find out.  Opinions?
Perhaps my simpler cast was not possible with earlier C compilers?  Just a hunch ...

Well, it's been around in it's present form since v7.6.6 (according to Bcx_Revisions.txt).  I'm surprised that no one encountered/reported this since then.

I think that it should be okay to modernize the macro.  But I'm just some guy on the net... :)

AIR.

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2392
    • View Profile
Re: Casting off.....
« Reply #4 on: May 15, 2024, 10:25:51 PM »
I don't know what I'll break if I change the BCX CAST macro to this but there's one way to find out.  Opinions?
Perhaps my simpler cast was not possible with earlier C compilers?  Just a hunch ...

Well, it's been around in it's present form since v7.6.6 (according to Bcx_Revisions.txt).  I'm surprised that no one encountered/reported this since then.

I think that it should be okay to modernize the macro.  But I'm just some guy on the net... :)

AIR.

Thanks ... I already made the change and noted it in Revisions. 

If someone needs the prior version of CAST(), it's easy to locate.

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2392
    • View Profile
Re: Casting off.....
« Reply #5 on: May 16, 2024, 09:22:48 AM »
The CAST example in the BCX Help File needs to be updated thusly,
in order for all modern compilers to treat the cast legitimately.

 UNION MyUnion
   MyInt  AS DOUBLE
   MyChar AS UCHAR
 END UNION
 
 DIM Example AS MyUnion
 DIM longvar AS LONG
 
 Example.MyChar = 255
 
 'longvar = (LONG) Example                          ' This statement will -NOT- compile with any compiler.
 
 longvar = (LONG) Example.MyChar              ' This statement WILL compile with any C/C++ compiler.
 longvar = CAST(LONG, Example.MyChar)     ' This statement WILL also compile, using the CAST macro.
 
 PRINT longvar                                             ' Should PRINT 255
 
 PAUSE




Robert

  • Hero Member
  • *****
  • Posts: 1256
    • View Profile
Re: Casting off.....
« Reply #6 on: May 16, 2024, 11:28:23 AM »
The CAST example in the BCX Help File needs to be updated thusly,
in order for all modern compilers to treat the cast legitimately.

 UNION MyUnion
   MyInt  AS DOUBLE
   MyChar AS UCHAR
 END UNION
 
 DIM Example AS MyUnion
 DIM longvar AS LONG
 
 Example.MyChar = 255
 
 'longvar = (LONG) Example                          ' This statement will -NOT- compile with any compiler.
 
 longvar = (LONG) Example.MyChar              ' This statement WILL compile with any C/C++ compiler.
 longvar = CAST(LONG, Example.MyChar)     ' This statement WILL also compile, using the CAST macro.
 
 PRINT longvar                                             ' Should PRINT 255
 
 PAUSE

Revised, as requested, and uploaded to

https://bcxbasiccoders.com/smf/index.php?PHPSESSID=5fd80cded33e60d912ca74e4d49229aa&topic=1053.msg5450

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2392
    • View Profile
Re: Casting off.....
« Reply #7 on: May 16, 2024, 11:54:49 AM »

Revised, as requested, and uploaded to

https://bcxbasiccoders.com/smf/index.php?PHPSESSID=5fd80cded33e60d912ca74e4d49229aa&topic=1053.msg5450

Thanks Robert!

The revision works with the deprecated, as well as the forthcoming revised, implementation of CAST().

Vortex

  • Full Member
  • ***
  • Posts: 132
    • View Profile
Re: Casting off.....
« Reply #8 on: May 16, 2024, 02:39:42 PM »
Hi Kevin,

In the code below ( my DLL to module definition file converter ) , replacing the original line :

Code: [Select]
FPRINT hFile, CHR$(34) , (char *)(*AddrOfNames+(LPBYTE)hMod) , CHR$(34)
with this one :

Code: [Select]
FPRINT hFile, CHR$(34) , KAST(char *,*AddrOfNames+KAST(LPBYTE,hMod)) , CHR$(34)
outputs the translation :

Code: [Select]
fprintf(hFile,"%s% d%s\n",chr(34),(int)KAST(char*,*AddrOfNames+KAST(LPBYTE,hMod)),chr(34));
Here in the line  (int)KAST(char*,  ....  the extra cast (int)  should not appear.

Code: [Select]
$FILETEST OFF

MACRO KAST(to_type, old_obj) = ((to_type)(old_obj))

DIM hMod AS HMODULE
DIM pNThdr AS PIMAGE_NT_HEADERS
DIM pDesc AS PIMAGE_EXPORT_DIRECTORY
DIM NumbOfNames AS DWORD
DIM i AS DWORD

DIM AddrOfNames AS DWORD PTR
DIM cmd$, ext$, deffile$

IF ARGC = 1 THEN

    PRINT "Usage : DllToDef.exe DllFile.dll"
    END

END IF

cmd$ = COMMAND$(1)
hMod = LOADLIBRARY(cmd$)

IF hMod =0 THEN

    PRINT "Error : " & cmd$ & " could not be loaded."
    END

END IF

ext$ = BCXSPLITPATH$(cmd$, FEXT)

pNThdr = KAST(PIMAGE_NT_HEADERS, (KAST(LPBYTE, hMod) + KAST(PIMAGE_DOS_HEADER, hMod)->e_lfanew))

pDesc = KAST(PIMAGE_EXPORT_DIRECTORY, (KAST(LPBYTE, hMod) + pNThdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress))

NumbOfNames = pDesc -> NumberOfNames;

IF NumbOfNames = 0 THEN
    PRINT cmd$ & " does not export any function(s)."
    FreeLibrary(hMod)
    END
END IF

deffile$ = BCXSPLITPATH$(cmd$, FNAME)+".def"

OPEN deffile$ FOR OUTPUT AS hFile

IF hFile==0 THEN

    PRINT "Cannot create the .def file."
    FreeLibrary(hMod)
    END

ENDIF

FPRINT hFile, "LIBRARY ", BCXSPLITPATH$(cmd$, FNAME)
FPRINT hFile, "EXPORTS"

AddrOfNames = KAST(DWORD *, (KAST(LPBYTE, hMod) + (size_t)pDesc -> AddressOfNames))

NumbOfNames = NumbOfNames-1

FOR i = 0 TO NumbOfNames

    FPRINT hFile, CHR$(34) , (char *)(*AddrOfNames+(LPBYTE)hMod) , CHR$(34)
    AddrOfNames = AddrOfNames+1

NEXT i

CLOSE hFile

PRINT cmd$ & " exports" & NumbOfNames+1 & " functions."

FreeLibrary(hMod)

Vortex

  • Full Member
  • ***
  • Posts: 132
    • View Profile
Re: Casting off.....
« Reply #9 on: May 16, 2024, 02:48:59 PM »
This one solves the issue :

Code: [Select]
DIM temp AS char *
.
.
.
FOR i = 0 TO NumbOfNames

    temp = KAST(char *,*AddrOfNames+KAST(LPBYTE,hMod))
    FPRINT hFile, CHR$(34) , temp , CHR$(34)
    AddrOfNames = AddrOfNames+1

NEXT

The translation is correct :

Code: [Select]
for(i=0; i<=NumbOfNames; i++)
    {
      temp=KAST(char*,*AddrOfNames+KAST(LPBYTE,hMod));
      fprintf(hFile,"%s%s%s\n",chr(34),temp,chr(34));
      AddrOfNames+=1;
    }

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2392
    • View Profile
Re: Casting off.....
« Reply #10 on: May 16, 2024, 03:29:20 PM »
Hi Erol,

Glad you found a solution. 

When translating PRINT / FPRINT statements, if BCX cannot determine an arguments type, it defaults to int.

Sometimes attaching one of the BASIC sigils, !,#,$,% to a print argument will help BCX output the desired formatting.


Vortex

  • Full Member
  • ***
  • Posts: 132
    • View Profile
Re: Casting off.....
« Reply #11 on: May 16, 2024, 03:44:36 PM »
Hi Kevin,

Thanks. Kindly, could you integrate the KAST macro to the BCX translator?

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 2392
    • View Profile
Re: Casting off.....
« Reply #12 on: May 16, 2024, 05:36:14 PM »
Hi Kevin,

Thanks. Kindly, could you integrate the KAST macro to the BCX translator?

Yes -- it has already been added to the forthcoming BCX 8.0.9