How to Use some Implicit Conversion for getting compatibility from Zstring to Ubyte in FB

Forum for discussion about the documentation project.
Post Reply
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

How to Use some Implicit Conversion for getting compatibility from Zstring to Ubyte in FB

Post by fxm »

Since the introduction of the 'Zstring' type in FreeBASIC by v1ctor (through already fbc version 0.13 beta in April 2005!), this compatibility from 'Zstring' to 'Ubyte' exists (if using particular syntax recalled a little from time to time).
Some people may have used it consciously. No doubt more people did so by inattention, not realizing that they were in principle making an invalid and forbidden assignment, but luckily corrected under the hood by an implicit conversion rule of compiler that was unknown to them.

A 'ZString' is a C-style fixed-size array of chars (by 'Ubyte' coded). It has no descriptor so it is faster to pass it as an argument to procedures. FreeBASIC avoids any overflow that could occur, by truncating the content when assigning it another string.
A stop mark (consisting of ASCII character with code 0) is appended to the end of the string. This must be taken into account when reserving space for a 'Zstring', since the final null character also occupies one byte.
The character chain is read from the start address of the string until this stop marker is found. Therefore such an ASCII character (code 0) must never enter in the text of a 'ZString' or the string will be truncated exactly at this point.

1) Implicit conversion rule from 'Zstring' to 'Ubyte':
  • This implicit conversion, from 'Zstring' to 'Ubyte', will occur when only dereferencing a 'Zstring Ptr' as operand of a binary operator (as 'assignment', 'equal', '+', '*', ...), and when the other operand is of numeric type.
    In this case, an 'Ubyte' reference is returned (reference to the one character pointed), as if the provided address came from an 'Ubyte Ptr' (no longer from a 'Zstring Ptr').
    • (see also Zstring documentation page)
2) For beginner (or as wake-up call), quick reminder about the "classic" main syntaxes between 'Zstring' type and 'Ubyte' type:
  • Code: Select all

    '   Dim Z As Zstring * N
    '      Z          is of Zstring type
    '      Z[i]       is of Ubyte type (indexing operator on Z)
    '      *@Z        is of Zstring type (dereferencing operator applied on @Z)
    '      *(@Z+i)    is of Zstring type (dereferencing operator applied on @Z+i)
    '      (@Z)[i]    is of Zstring type (dereferencing operator with offset i applied on @Z)
    '      @(Z[i])    is of Ubyte Ptr type (address-of operator applied Z[i])
    
    '   Dim PZ As Zstring Ptr
    '      PZ         is of Zstring Ptr tpe
    '      *PZ        is of Zstring type (dereferencing operator applied on PZ)
    '      *(PZ+i)    is of Zstring type (dereferencing operator applied on PZ+i)
    '      PZ[i]      is of Zstring type (dereferencing operator with offset i applied on PZ)
    '      (*PZ)[i]   is of Ubyte type (indexing operator on (*PZ)))
    
    • But this implicit conversion rule will apply to '*@Z', '*(@Z+i)', '(@Z)', '*PZ', '*(PZ+i)', 'PZ', if these expressions are used as operand of a binary operator (as 'assignment', 'equal', '+', '*', ...) whose other operand is of numeric type.

3) Use cases of this implicit conversion rule (from 'Zstring' to 'Ubyte):
  • When this implicit conversion rule applies, such an expression as 'PZ' can be considered as a short-cut of '(*PZ)'.
    (PZ being a 'Zstring Ptr')

    Since '(*PZ)' and 'PZ[k]' are always numeric (each an 'Ubyte'), such equalities are true:
    • PZ = (*PZ)
      (*PZ) = PZ
      and even:
      PZ[i+k] = PZ[i][k]
      PZ[i][k] = PZ[i+k]

    Simple code example with a dereferenced 'Zstring Ptr' converted to an 'Ubyte' reference (as operand of an 'assignment' operator and a '+' operator):
    • Code: Select all

      Dim As Zstring * (14+1) z = "FreeBASIC     "
      Dim As Zstring Ptr pz = @z
      
      Print z
      z[10] = Asc("2")
      *(pz + 11) = Asc("0")              '' *(pz + 11) is converted to an Ubyte reference
      (*pz)[12] = Asc("1")
      pz[13] = Asc("8")                  '' pz[13] is converted to an Ubyte reference
      Print z
      
      For I As Integer = 10 To 13
        Print Str(z[I] - Asc("0"));
      Next I
      Print
      For I As Integer = 10 To 13
        Print Str((*pz)[I] - Asc("0"));
      Next I
      Print
      For I As Integer = 10 To 13
        Print Str(pz[I] - Asc("0"));     '' pz[I] is converted to an Ubyte reference
      Next I
      Print
      
      Sleep
      

      Code: Select all

      FreeBASIC
      FreeBASIC 2018
      2018
      2018
      2018
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: How to Use some Implicit Conversion for getting compatibility from Zstring to Ubyte in FB

Post by grindstone »

fxm wrote:...but luckily corrected under the wood by an implicit conversion rule...
I'm pretty sure you mean "under the hood". :-)
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to Use some Implicit Conversion for getting compatibility from Zstring to Ubyte in FB

Post by fxm »

Thanks.
Post Reply