Array Descriptor (split from Wiki Improvements)

Forum for discussion about the documentation project.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Wiki improvements

Post by MrSwiss »

fxm wrote:Do you always try to read between the lines of user posts before answering?
Yes, but apparently, I'm not very good at it. That's why I'm sometimes asking,
if my stated assumptions are correct, or for further clarifications.
NOTE: trying and succeeding isn't synonymous!
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Wiki improvements

Post by MrSwiss »

Back to business, again:
fxm wrote:In the array descriptor, I do not see a field to discriminate a fix-len array against a var-len array.
No, but there is a workaround:
1) check array bounds (save them, for comparison)
2) Erase(array)
3) check bounds again (compare)
4) if still the same bounds: array is static, otherwise,
if UBound(array) < LBound(array) then: the array is dynamic (uninitialized)
(maybe a dynamic temp. array needed, to keep values)

Proof of concept:

Code: Select all

Dim     Array1(1 To 10) As Integer  ' static
ReDim   Array2(1 To 10) As Integer  ' dynamic

Print "Array1("; Str(LBound(Array1)); " To "; Str(UBound(Array1)); ")"
Print "Array2("; Str(LBound(Array2)); " To "; Str(UBound(Array2)); ")"
Print

Print "erasing now ... done"
Erase Array1, Array2

Print
Print "Array1("; Str(LBound(Array1)); " To "; Str(UBound(Array1)); ")"
Print "Array2("; Str(LBound(Array2)); " To "; Str(UBound(Array2)); ")"

Sleep
RESULT wrote: Array1(1 To 10)
Array2(1 To 10)

erasing now ... done

Array1(1 To 10)
Array2(0 To -1)
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

Yes, but the question is to determine from inside a procedure whether the array passed as a parameter is a fix-len array or a var-len array.
When the code refers to the array by its own name, there is no problem because the array type is known implicitly.

Inside a procedure, this type of test on the passed array does not work because, for a static array, a temporary descriptor of array is passed and any changes really only work on the array data (changes on the descriptor values ​​appear operate locally):

Code: Select all

Sub erasing (Array() As Integer)
  Print "  From inside the procedure:"
  Print "    Array("; Str(LBound(Array)); " To "; Str(UBound(Array)); ")"
  Print "    Erasing now ... done"
  Erase Array
  Print "    Array("; Str(LBound(Array)); " To "; Str(UBound(Array)); ")"
End Sub

Dim     Array1(1 To 10) As Integer  ' static
ReDim   Array2(1 To 10) As Integer  ' dynamic

Print "Array1()"
erasing(Array1())
Print "  then, from the Array1() scope:"
Print "    Array1("; Str(LBound(Array1)); " To "; Str(UBound(Array1)); ")"
Print
Print "Array2()"
erasing(Array2())
Print "  then, from the Array2() scope:"
Print "    Array2("; Str(LBound(Array2)); " To "; Str(UBound(Array2)); ")"
Print

Sleep

Code: Select all

Array1()
  From inside the procedure:
    Array(1 To 10)
    Erasing now ... done
    Array(0 To -1)
  then, from the Array1() scope:
    Array1(1 To 10)

Array2()
  From inside the procedure:
    Array(1 To 10)
    Erasing now ... done
    Array(0 To -1)
  then, from the Array2() scope:
    Array2(0 To -1)
Note: In addition, 'Erase' from inside a procedure does not reset the elements of a fix-len array passed as parameter.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

coderJeff,

What exactly does 'Erase' do from inside a procedure when it applies to a fixed-len array passed as parameter?
Does it try to deallocate any thing?
'Erase' applied to a fix-len array passed as parameter is not full efficient, but is it safe code?

In any case, we can check that at least from inside a procedure:
- 'Erase' calls the destructor (if exists) of each element of a fix-len array passed as parameter.
- 'Erase' does not reset the elements of a fix-len array passed by parameter (no object elements re-construction or no numeric elements resetting to 0).
- Does it try to deallocate some memory, as for a var-len array?
I do not see how afterwards, in the main code, when the fix-len array goes out of its scope, a second destruction attempt seems to be well skipped (maybe through the state of the array descriptor passed by reference?).


[edit]
WARNING: 'Erase' used on a fix-len array passed by parameter causes a crash in FBC 64-bit (only seen afterwards).
To the following, use only FBC 32-bit to run the different examples.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

After deeper tests (with FBC 32-bit), I can conclude that:
- 'Erase' (from inside a procedure) seems to not attempt to deallocate some memory (maybe because the array data are not on the heap?)
- Otherwise the code seems to be safe (except for global fix-len arrays, see post below).
- But the only difference (for a user) when 'Erase' is called from inside a procedure (on fix-len array passed as parameter) is that the array elements are not reset (not cleared for numeric elements or not re-constructed for object elements like UDTs).
An information is returned from the procedure in order to skip the normal call of destructor at end of scope, through the array descriptor passed by reference, that 'Erase' resets (as if it were the descriptor of a var-len array).

A small code to check the behavior related to the constructor/destructor calls (three cases: 'Erase' called on an array name, 'Erase not called, and 'Erase' called on an array passed as parameter):

Code: Select all

Type UDT
  Dim AS Integer I
  Declare Constructor ()
  Declare Destructor ()
End Type
Constructor UDT
  Print "constructor ", @This
End Constructor
Destructor UDT
  Print "destructor ", @This
End Destructor

Sub erasing (array() As UDT)
  Erase array
  Print "array erased"
End Sub

For K As Integer = 1 To 3
  Scope
    Dim array(1 To 2) As UDT
    array(1).I = 111
    Print
    If K = 1 Then
      Print "call 'Erase'"
      Erase array
      Print "array erased"
    Elseif K = 2 Then
      Print "array not erased"
    Else
      Print "call Sub 'erasing'"
      erasing(array())
    End If
    Print
    Print Ubound(array), array(1).I
    Print "end of scope"
  End Scope
  Print
  Print "--------------------"
  Print
Next K

Sleep

Code: Select all

constructor   1703568
constructor   1703572

call 'Erase'
destructor    1703572
destructor    1703568
constructor   1703568
constructor   1703572
array erased

 2             0
end of scope
destructor    1703572
destructor    1703568

--------------------

constructor   1703568
constructor   1703572

array not erased

 2             111
end of scope
destructor    1703572
destructor    1703568

--------------------

constructor   1703568
constructor   1703572

call Sub 'erasing'
destructor    1703572
destructor    1703568
array erased

 2             111
end of scope

--------------------
Note: If really 'Erase' (from inside a procedure) does not attempt to deallocate some memory (maybe because the array data are not on the heap), we could replace this skipped deallocation (compared to a var-len array) by a re-construction of the object elements or by a clearing of the numeric elements.
In that case, the object elements (of fix-len arrays) should be destructed at scope end (or program end for global arrays) as the normal behavior when 'Erase' is used on an explicit array name (this would also fix the bug of the post below). Therefore, the trick of resetting the passed descriptor of a fix-len array should be no longer used (more logical to not modify the descriptor of a fix-len array).


Annex 1: Code to demonstrate that 'Erase' presently resets the descriptor of a fix-len array (of UDT) passed as parameter, a trick, but illogical:
(a trick in order that the calling code does not destroy a second time the array elements when program goes out of its scope)

Code: Select all

Type arrayDimensionDescriptor
  Dim As Uinteger nbOfElements  ' number of elements: (highBound-lowBound+1)
  Dim As Integer lowBound       ' lbound
  Dim As Integer highBound      ' ubound
End Type

Type arrayDescriptor
  Dim As Any Ptr nullIndexesAddress  ' pointer to the real or virtual element: @array(0, 0,...)
  Dim As Any Ptr minIndexesAddress   ' pointer to the first real element: @array(lbound1, lbound2,...)
  Dim As Uinteger globalSize         ' "global" size in bytes: (ubound1-lbound1+1)*(ubound2-lbound2+1).....*(size of 1 element)
  Dim As Uinteger elementSize        ' size of one element in bytes
  Dim As Uinteger nbOfDimensions     ' number of dimensions
  Dim As arrayDimensionDescriptor arrayDimensions(1 to 8)  ' max number of dimensions = 8
End Type                                                   '   (numbered from 1 to 8)

private Function arrayDescriptorGetPtrFunction (Byval p As Any Ptr) As Any Ptr
  Return p
End function

#macro arrayDescriptorPtr(array, p)
  Scope
    Dim As Function (() As Typeof((array))) As Any Ptr f
    f = Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorGetPtrFunction)
    p = f(array())
  End Scope
#endmacro

'------------------------------------------------------------------------------------

Sub printArrayDescriptor (Byval p As Any Ptr)
  Dim As arrayDescriptor Ptr pu = p
  Print "[@array descriptor: "; pu; "]"
  Print "  @array(all_null_indexes)   ="; pu->nullIndexesAddress
  Print "  @array(all_min_indexes)    ="; pu->minIndexesAddress
  Print "  array_total_size_in_bytes  ="; pu->globalSize
  Print "  array_element_size_in_bytes="; pu->elementSize
  Print "  number_of_array_dimensions ="; pu->nbOfDimensions
  For i As Integer = 1 to pu->nbOfDimensions
    Print "  [dimension number:"; i; "]"
    Print "    number_of_elements="; pu->arrayDimensions(i).nbOfElements
    Print "    min_index         ="; pu->arrayDimensions(i).lowBound
    Print "    max_index         ="; pu->arrayDimensions(i).highBound
  Next i
End Sub

'------------------------------------------------------------------------------------

Type UDT
  Dim AS Integer I
  Declare Constructor ()
  Declare Destructor ()
End Type
Constructor UDT
  Print "constructor ", @This
End Constructor
Destructor UDT
  Print "destructor ", @This
End Destructor

Sub erasing (array() As UDT)
  Dim As Any Ptr p
  arrayDescriptorPtr(array, p)
  printArrayDescriptor(p)
  Print
  Print "Erasing the fix-len array:"
  Print
  Erase array
  printArrayDescriptor(p)
  Print
End Sub

Scope
  Dim As UDT array(0 To 1)
  erasing(array())
  Print "Going out the array scope:"
  Print
End Scope

Sleep

Code: Select all

constructor   1703572
constructor   1703576
[@array descriptor: 1703540]
  @array(all_null_indexes)   =1703572
  @array(all_min_indexes)    =1703572
  array_total_size_in_bytes  =8
  array_element_size_in_bytes=4
  number_of_array_dimensions =1
  [dimension number: 1]
    number_of_elements=2
    min_index         = 0
    max_index         = 1

Erasing the fix-len array:

destructor    1703576
destructor    1703572
[@array descriptor: 1703540]
  @array(all_null_indexes)   =0
  @array(all_min_indexes)    =0
  array_total_size_in_bytes  =0
  array_element_size_in_bytes=4
  number_of_array_dimensions =1
  [dimension number: 1]
    number_of_elements=0
    min_index         = 0
    max_index         = 0

Going out the array scope:
Annex 2: Code to demonstrate that if 'Erase' did not reset the descriptor of a fix-len array (of UDT) passed as parameter, but re-constructed the array elements, all would be right when program would go out of its scope (the re-constructed array elements properly destroyed when program goes out of its scope):

Code: Select all

Type arrayDimensionDescriptor
  Dim As Uinteger nbOfElements  ' number of elements: (highBound-lowBound+1)
  Dim As Integer lowBound       ' lbound
  Dim As Integer highBound      ' ubound
End Type

Type arrayDescriptor
  Dim As Any Ptr nullIndexesAddress  ' pointer to the real or virtual element: @array(0, 0,...)
  Dim As Any Ptr minIndexesAddress   ' pointer to the first real element: @array(lbound1, lbound2,...)
  Dim As Uinteger globalSize         ' "global" size in bytes: (ubound1-lbound1+1)*(ubound2-lbound2+1).....*(size of 1 element)
  Dim As Uinteger elementSize        ' size of one element in bytes
  Dim As Uinteger nbOfDimensions     ' number of dimensions
  Dim As arrayDimensionDescriptor arrayDimensions(1 to 8)  ' max number of dimensions = 8
End Type                                                   '   (numbered from 1 to 8)

private Function arrayDescriptorGetPtrFunction (Byval p As Any Ptr) As Any Ptr
  Return p
End function

#macro arrayDescriptorPtr(array, p)
  Scope
    Dim As Function (() As Typeof((array))) As Any Ptr f
    f = Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorGetPtrFunction)
    p = f(array())
  End Scope
#endmacro

'------------------------------------------------------------------------------------

Sub printArrayDescriptor (Byval p As Any Ptr)
  Dim As arrayDescriptor Ptr pu = p
  Print "[@array descriptor: "; pu; "]"
  Print "  @array(all_null_indexes)   ="; pu->nullIndexesAddress
  Print "  @array(all_min_indexes)    ="; pu->minIndexesAddress
  Print "  array_total_size_in_bytes  ="; pu->globalSize
  Print "  array_element_size_in_bytes="; pu->elementSize
  Print "  number_of_array_dimensions ="; pu->nbOfDimensions
  For i As Integer = 1 to pu->nbOfDimensions
    Print "  [dimension number:"; i; "]"
    Print "    number_of_elements="; pu->arrayDimensions(i).nbOfElements
    Print "    min_index         ="; pu->arrayDimensions(i).lowBound
    Print "    max_index         ="; pu->arrayDimensions(i).highBound
  Next i
End Sub

'------------------------------------------------------------------------------------

Type UDT
  Dim AS Uinteger I
  Declare Constructor ()
  Declare Destructor ()
End Type
Constructor UDT
  Print "constructor ", @This
End Constructor
Destructor UDT
  Print "destructor ", @This
End Destructor

Sub erasing (array() As UDT)
  ' get pointer to descriptor
    Dim As Integer Ptr p
    arrayDescriptorPtr(array, p)
  printArrayDescriptor(p)
  Print array(0).I
  Print
  ' save descriptor
    Dim As Integer I(4 + p[4] * 3)
    For K As Integer = Lbound(I) To Ubound(I)
      I(K) = p[K]
    Next K
  Print "Erasing the fix-len array:"
  Print
  ' bugged erase array
    Erase array
  printArrayDescriptor(p)
  Print Cptr(Uinteger Ptr, I(0))[0]
  Print
  Print "Restoring the descriptor and re-constructing the array elements:"
  Print
  ' restore descriptor
    For K As Integer = Lbound(I) To Ubound(I)
      p[K] = I(K)
    Next K
  printArrayDescriptor(p)
  Print array(0).I
  ' re-construct array elements
    Dim As Any Ptr p0 = New(Cast(Any Ptr, p[1])) Typeof((array))[p[2] \ p[3]]
  Print array(0).I
  Print
End Sub

Scope
  Dim As UDT array(0 To 1)
  array(0).I = 111
  erasing(array())
  Print "Going out the array scope:"
  Print
End Scope

Sleep

Code: Select all

constructor   1703572
constructor   1703576
[@array descriptor: 1703540]
  @array(all_null_indexes)   =1703572
  @array(all_min_indexes)    =1703572
  array_total_size_in_bytes  =8
  array_element_size_in_bytes=4
  number_of_array_dimensions =1
  [dimension number: 1]
    number_of_elements=2
    min_index         = 0
    max_index         = 1
111

Erasing the fix-len array:

destructor    1703576
destructor    1703572
[@array descriptor: 1703540]
  @array(all_null_indexes)   =0
  @array(all_min_indexes)    =0
  array_total_size_in_bytes  =0
  array_element_size_in_bytes=4
  number_of_array_dimensions =1
  [dimension number: 1]
    number_of_elements=0
    min_index         = 0
    max_index         = 0
111

Restoring the descriptor and re-constructing the array elements:

[@array descriptor: 1703540]
  @array(all_null_indexes)   =1703572
  @array(all_min_indexes)    =1703572
  array_total_size_in_bytes  =8
  array_element_size_in_bytes=4
  number_of_array_dimensions =1
  [dimension number: 1]
    number_of_elements=2
    min_index         = 0
    max_index         = 1
111
constructor   1703572
constructor   1703576
0

Going out the array scope:

destructor    1703576
destructor    1703572
[edit]
WARNING: 'Erase' used on a fix-len array passed by parameter causes a crash in FBC 64-bit (only seen afterwards).
Use only FBC 32-bit to run the different examples.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

Bug when 'Erase' is used on global fix-len arrays passed as parameters (see with FBC 32-bit)

For static fix-len arrays or shared fix-len arrays passed as parameters, 'Erase' in the procedure call the destructor for each object element, but at program end, the destructor is called a second time on the same object elements (maybe just an oversight compared to the behavior with non-global fix-len arrays where that works).

Example with Shared:

Code: Select all

Type UDT
  Dim AS Integer I
  Declare Constructor ()
  Declare Destructor ()
End Type
Constructor UDT
  Print "constructor ", @This
End Constructor
Destructor UDT
  Print "destructor ", @This
End Destructor

Sub erasing (array() As UDT)
  Erase array
  Print "array erased"
End Sub

Dim Shared array(1 To 2) As UDT
Print
Print "call Sub 'erasing'"
erasing(array())
Print
Output (when executing the above code from a console window, for example):

Code: Select all

constructor   4239392
constructor   4239396

call Sub 'erasing'
destructor    4239396
destructor    4239392
array erased

destructor    4239396
destructor    4239392
As fix proposal, see the note in post above.


[edit]
WARNING: 'Erase' used on a fix-len array passed by parameter causes a crash in FBC 64-bit (only seen afterwards).
Use only FBC 32-bit to run the different examples.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

coderJeff,
About my 3 previous posts here (on the bad behavior of 'Erase' when used on a fix-len array passed as parameter), I think that my analysis is now quite complete.
I think to wait a little (for your reaction for example) before filling in a bug report or/and updating the documentation.

I think I have been deceived because I made all my previous tests with FBC 32-bit (without any crash).

Finally (as that always crashes with FBC 64-bit), all this could come from the fact that 'Erase', used on a fix-len array passed as parameter, proceeds as for a var-len array (so, it destroys the array elements and tries to free the associated memory).

There is no direct information in the array descriptor to discriminate between fix-len array and var-len array.
Instead of add this information, perhaps can one detect that the array data are not on the heap?


If this behavior is not fixable, a proposal for updating the 'Erase' documentation page:
Erase cannot not be used on fixed-size arrays passed as parameters in a procedure. FreeBASIC cannot prevent you trying this at compile-time, but the results at run-time will be undefined.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Wiki improvements

Post by coderJeff »

fxm, I think you have a good understanding of what's going on.

In compiler there are 2 types of array storage:
- dynamic (variable length, resizable, has a descriptor)
- static (fixed length, no descriptor)

And 3 types of arrays:
- string (some times called var-len, internally in older code)
- UDT with constructors and/or destructors
- everything else (not a string, no ctor/dtor)

Depending on static/dynamic storage (as determined at compile time) determines ERASE and REDIM behaviours:

ERASE dynamic array (also known as "Array Erase" internally)
- call destructors (if they exist)
- free memory
- reset descriptor

ERASE static array (also known as "Array Clear" internally)
- call destructors (if they exist)
- call constructors (if they exist), otherwise clear (zero) memory

As you have noticed, when static arrays are passed as parameter, fbc creates a temporary dynamic array descriptor to satisfy the procedure call. However, no information exists in the array descriptor to indicate that the descriptor is temporary and points to static (fixed-len, no descriptor) data.

It can be fixed if we are willing to break binary compatibility, by changing the array descriptor to track if memory should be freed or not. Can be tricky because fbc itself uses arrays. If we do this though, it can clean up some dead code out of the rtlib that's only been kept for backwards binary compatibility purpose, and would fix the issue you are seeing with ERASE.

In either case, documenting the limitations of static array passed as parameter and ERASE is worthwhile.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

Thank you for your reply.
coderJeff wrote:It can be fixed if we are willing to break binary compatibility, by changing the array descriptor to track if memory should be freed or not. Can be tricky because fbc itself uses arrays. If we do this though, it can clean up some dead code out of the rtlib that's only been kept for backwards binary compatibility purpose, and would fix the issue you are seeing with ERASE
This would be a solution at compile-time, when a descriptor is created following the call of a procedure passing a fixed-size array.

But is there a solution at run-time (with the current descriptor structure)?
Can we do anything at run-time, for example with the value of the array data address (second descriptor field) to detect whether the array data is on the heap or not?
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

coderJeff wrote:documenting the limitations of static array passed as parameter and ERASE is worthwhile
KeyPgErase → fxm [Adding a note to not use Erase on fixed-size arrays passed as parameters in a procedure]
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Wiki improvements

Post by coderJeff »

fxm wrote:But is there a solution at run-time (with the current descriptor structure)?
Can we do anything at run-time, for example with the value of the array data address (second descriptor field) to detect whether the array data is on the heap or not?
I think not, because it's practically impossible. Knowing if a pointer is on stack or heap (malloc), requires knowing where all the stacks are and heaps are. How the system might provide that information at run time would be system specific, if it's available at all.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Wiki improvements

Post by fxm »

So, only an update of the documentation and no bug report for this behavior of 'Erase' with fixed-size arrays passed as parameters (in the same way as for 'Redim').
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Wiki improvements

Post by coderJeff »

If we fix ERASE behaviour, like it were a bug, it requires breaking binary (backwards) compatibility, which I am personally OK with, and we get better compiler & rtlib as a result, properly handling temporary array descriptors that point to static data. If we don't fix it (pretend it is not a bug), then current behaviour is "by design" :)
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Re: Wiki improvements

Post by Juergen Kuehlwein »

coderJeff wrote:
It can be fixed if we are willing to break binary compatibility, by changing the array descriptor to track if memory should be freed or not. Can be tricky because fbc itself uses arrays. If we do this though, it can clean up some dead code out of the rtlib that's only been kept for backwards binary compatibility purpose, and would fix the issue you are seeing with ERASE
Maybe there is easy solution for this: Currently the nbOfDimensions member (UINTEGER) of the array descriptor is used as a single value. But in fact we need only bit 0,1,2 and 3 of it, because there is a maximum of 8 dimensions. Treating it as a bitmask we would have 28 bits free for other values or flags. NbOfDimensions is used only internally, so masking the lower 4 bits out where needed shouldn´t be a problem. If we made bit 4 (whichever you like) a flag for a fixed size array and let it default to zero (0 = dynamic array, 1 = fixed size array), it would even be compatible with what we have right now.

I don´t know, if libraries or saved data can contain an array descriptor at all. But even if this is the case, we would then have our flag bit set to zero, which falsely tells us, it could be redimed or erased. But that´s, what we have right now anyway. Any new code will be able to prevent this by raising a compiler error or runtime error.

What do you think?


JK
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Wiki improvements

Post by coderJeff »

JK, you have the right ideas. Regardless, it's still a binary compatibility break. It's probably not as bad as I make it out to be, that's just the attitude I must have going in to it, preparing users for the worst.

fbc itself, IIRC, mostly static arrays are used like lookup tables. There are a few places where REDIM and ERASE are used in fbc to watch out for. I'd have to have a much closer look to determine if that causes any issue in the transition.

Compiling fully from source code for any version of fbc should not be an issue since all new code is generated.

So, will be no problem for users if versions are all same:
- compile fbc 1.07 & link 1.07 user lib -- OK, changes fully implemented
- compile fbc 1.06 & link 1.06 user lib -- OK, change doesn't exist yet, same bugs as always

It's only where pre-compiled user libs (binary releases) exist that might have usage issues, but only if they use array descriptors:
- compile fbc 1.07 & link 1.06 user lib and 1.07 rtlib -- Probably OK, same bugs as already reported within 1.06 user lib only. Should be avoided. Array descriptor size change makes this a full break if the user lib uses array descriptors.
- compile fbc 1.06 & link 1.07 user lib and 1.06 rtlib -- will probably die since extra bits in 1.07 lib will not be understood by older 1.06 lib. Should be avoided. Array descriptor size change makes this a full break if the user lib uses array descriptors.
Post Reply