Menu

#650 BYREF/typedefs allow pointers to [Z/W]STRING * N

open
nobody
None
compiler
2019-09-22
2013-01-16
dkl
No

BYREF parameters or typedefs can be used to create pointers to fixed-length strings:

sub f1( byref x as zstring * 1 )
    print x
end sub

f1( "abc" )


type S as zstring * 1
dim p as S ptr

Also, BYREF function results are/will be affected:

function f2( ) byref as zstring * 1
    function = "abc"
end function
print f2( )

However the compiler does not allow direct declarations such as:

dim p as zstring * 123 ptr

The compiler should be more consistent, allowing it either always or never. Since currently the compiler is internally not able to represent a pointer to a fixed-length string (the length is not preserved on the expression type when taking the address of a variable like that), it's probably best to disallow it all-together.

Related

Bugs: #867
Bugs: #999

Discussion

  • dkl

    dkl - 2013-02-18

    As for typedefs, this raises another question. What should the following do?

    type A as zstring * 2
    type B as A * 3
    print sizeof( A ), sizeof( B )
    

    Currently the *3 just overrides the *2, this is inconsistent with how typedefs sum up PTRs at least. Should zstring * 2 * 3 be multiplied together to give a zstring * 6?

    Also, should a byref s as zstring * 1 be different from a byref s as zstring? (that's currently hard to distinguish in cSymbolType() because their type length is the same)

     

    Last edit: dkl 2013-02-18
  • dkl

    dkl - 2013-05-16

    Possibly related:

    http://www.freebasic.net/forum/viewtopic.php?f=3&t=21188&p=187266#p187266
    
    sub foo( array() as zstring * 32 )
        print array(0), sizeof( array(0) )
    end sub
    
        dim array(0 to 0) as zstring * 32
        array(0) = "hello"
    
        print array(0), sizeof( array(0) )
        foo( array() )
    
     
  • fxm (freebasic.net)

    Consequently, the address of each array element (except the first) is badly computed in the procedure body:

    sub foo( array() as zstring * 32 )
        print @array(0), @array(1), @array(2)
    end sub
    
    dim array(0 to 2) as zstring * 32
    
    print @array(0), @array(1), @array(2)
    foo( array() )
    
     

    Last edit: fxm (freebasic.net) 2013-06-02
  • fxm (freebasic.net)

    For the problem of passing a zstring array to a procedure, a fix could be to use the 'element_len' field in the descriptor and not the size of the declared parameter type.

    This could be even applied systematically to all arrays passed as parameters to procedures.

    See the other bug reports BUG #867 and BUG #911.

    Example:
    (For fbc rev 1.07, use 'fb_ArrayGetDesc()' instead of 'FBC.ArrayDescriptorPtr()' for fbc rev 1.08 as here)

    #include "fbc-int/array.bi"
    
    Sub prnt_zstring_array (array() As Zstring * 16)
        For n as integer = lbound(array) to ubound(array)
            Print "'" & array(n) & "'"
        Next n
    End Sub
    
    Sub prnt_zstring_array_using_element_len_in_descriptor (array() As Zstring * 16)
        Dim as FBC.FBARRAY ptr pd = FBC.ArrayDescriptorPtr(array())
        #define _array(i) *Cast(Zstring Ptr, pd->index_ptr + pd->element_len * (i))
        For n as integer = lbound(array) to ubound(array)
            Print _array(n)
        Next n
    End Sub
    
    Dim As Zstring * 16 z(-1 To 1)
    z(-1) = "FreeBASIC"
    z(0) = "rev 1.08"
    z(1) = "for win64"
    
    prnt_zstring_array(z())
    Print
    prnt_zstring_array_using_element_len_in_descriptor(z())
    
    Sleep
    
    Output:
    ''
    'rev 1.08'
    'ev 1.08'
    
    'FreeBASIC'
    'rev 1.08'
    'for win64'
    
     

    Last edit: fxm (freebasic.net) 2019-09-24

Log in to post a comment.

Auth0 Logo