(Re)Dim with a negative size just works. Bug or Feature?

Just starting out? Need help? Post your questions and find answers here.
User avatar
NicTheQuick
Addict
Addict
Posts: 1503
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

(Re)Dim with a negative size just works. Bug or Feature?

Post by NicTheQuick »

Hi guys.

In this post I found out that it seems to be no problem using a size of -1 for Dim or ReDim.

Example with Dim:

Code: Select all

Define size.i = -1
Dim arr.i(size)

Debug ArraySize(arr())
Example with ReDim:

Code: Select all

Dim arr.i(0)

Debug ArraySize(arr())

Define size.i = -1
ReDim arr(size)

Debug ArraySize(arr())
An issue occurs if you try to increase the size again afterwards.

Code: Select all

Define size.i = -1
Dim arr.i(size)

Debug ArraySize(arr())

ReDim arr(0) ; --> Invalid memory access

Debug ArraySize(arr())
In the original code setting the array size to -1 is very helpful. Because only with an array of size -1 you can create an empty JSON array.

So I think at first look it is a bug that you can set the size to -1 and even ArraySize() reports the size as -1. And of course it is a bug that increasing the size results in an invalid memory access. But on the other hand it is very helpful when working with JSON and you don't want to program in special cases for empty arrays.

Let's discuss together if this should be moved to the Bug forum.

I tested it with PureBasic 6.20 (x64) on Ubuntu 24.04.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: (Re)Dim with a negative size just works. Bug or Feature?

Post by Little John »

NicTheQuick wrote: Fri Apr 25, 2025 11:14 am Example with Dim:

Code: Select all

Define size.i = -1
Dim arr.i(size)

Debug ArraySize(arr())
Example with ReDim:

Code: Select all

Dim arr.i(0)

Debug ArraySize(arr())

Define size.i = -1
ReDim arr(size)

Debug ArraySize(arr())
Both examples raise an error here with PB 6.20 (x64) on Windows.

NicTheQuick wrote: Fri Apr 25, 2025 11:14 am An issue occurs if you try to increase the size again afterwards.
Using ReDim() does not work and is not necessary. Use Dim() instead.

NicTheQuick wrote: Fri Apr 25, 2025 11:14 am In the original code setting the array size to -1 is very helpful. Because only with an array of size -1 you can create an empty JSON array.
I think the official way to achieve that goal is using FreeArray().
User avatar
NicTheQuick
Addict
Addict
Posts: 1503
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: (Re)Dim with a negative size just works. Bug or Feature?

Post by NicTheQuick »

Little John wrote: Fri Apr 25, 2025 4:11 pm Both examples raise an error here with PB 6.20 (x64) on Windows.
Good to know. Then this might be a Linux bug.
Little John wrote: Fri Apr 25, 2025 4:11 pm
NicTheQuick wrote: Fri Apr 25, 2025 11:14 am An issue occurs if you try to increase the size again afterwards.
Using ReDim() does not work and is not necessary. Use Dim() instead.
I don't understand what you mean. Of course you have to use ReDim after an array was already created with Dim.
Little John wrote: Fri Apr 25, 2025 4:11 pm
NicTheQuick wrote: Fri Apr 25, 2025 11:14 am In the original code setting the array size to -1 is very helpful. Because only with an array of size -1 you can create an empty JSON array.
I think the official way to achieve that goal is using FreeArray().
You mea like this?

Code: Select all

EnableExplicit

Structure JSON
	Array Test$(0)
EndStructure

Global NewList Names$()
; AddElement(Names$()) : Names$() = "Quin"
; AddElement(Names$()) : Names$() = "Sam"
; AddElement(Names$()) : Names$() = "Malia"

Define j.JSON, i.i = 0
If ListSize(Names$()) > 0
	ReDim j\Test$(ListSize(Names$()) - 1)
	ForEach Names$()
		j\Test$(i) = Names$()
		i + 1
	Next
Else
	FreeArray(j\Test$())
EndIf
Debug "ArraySize: " + Str(ArraySize(j\Test$()))
Define JSONID.i = CreateJSON(#PB_Any)
InsertJSONStructure(JSONValue(JSONID), @j, JSON)
Debug ComposeJSON(JSONID)
FreeJSON(JSONID)
You are right. That works. But it's very confusing. I never liked that PureBasic required you to specify the upper bound of the array instead of the size of the array. But we also know that this is inconsistent with static arrays in structures, where you actually specify the size.
Well, there's nothing you can do about it now anyway.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Quin
Addict
Addict
Posts: 1124
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: (Re)Dim with a negative size just works. Bug or Feature?

Post by Quin »

NicTheQuick wrote: Sat Apr 26, 2025 5:40 pm You are right. That works. But it's very confusing. I never liked that PureBasic required you to specify the upper bound of the array instead of the size of the array. But we also know that this is inconsistent with static arrays in structures, where you actually specify the size.
Well, there's nothing you can do about it now anyway.
I fully agree with you, I always found this confusing and it's the reason I used to use linked lists instead of arrays for basically everything in PB. As I've gotten more experienced I've tried to ditch that habbit, but when I get caught up by something like this damn is it tempting. Especially for JSON :twisted:
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: (Re)Dim with a negative size just works. Bug or Feature?

Post by Little John »

NicTheQuick wrote: Sat Apr 26, 2025 5:40 pm
Little John wrote: Fri Apr 25, 2025 4:11 pm
NicTheQuick wrote: Fri Apr 25, 2025 11:14 am An issue occurs if you try to increase the size again afterwards.
Using ReDim() does not work and is not necessary. Use Dim() instead.
I don't understand what you mean. Of course you have to use ReDim after an array was already created with Dim.
No. “Have to use ReDim” is wrong, generally speaking. We can write this, for instance:

Code: Select all

Global Dim Foo.i(0)  ; We want a global array, but don't know its size yet.

Procedure Init (n.i)
   Dim Foo(n-1)
   ; ...
EndProcedure
Using Redim() on an existing array is only required if you want to preserve its content, while using Dim() on an existing array will reset its contents to zero ( see https://www.purebasic.com/documentation ... e/dim.html ).
And in the special case we are talking about, when we have an empty array and want to increase its size, we have to use Dim(), as I wrote ( see https://www.purebasic.com/documentation ... array.html ).
So your issue occurs because you are using ReDim() instead of Dim() at that point.

Everything in this context works correctly and is well documented, with one exception:
Dim Foo(-1) works on Linux and not on Windows.

Dim Foo(-1) is not required, because FreeArray() is the documented way to create an empty array.
Of course the inconsistency should be fixed, Fred either should enable it on Windows, or disable it on Linux (I don't know how it currently works on the other supported operating systems).
Post Reply