Can a pointer be a negative number?

Just starting out? Need help? Post your questions and find answers here.
AZJIO
Addict
Addict
Posts: 2223
Joined: Sun May 14, 2017 1:48 am

Can a pointer be a negative number?

Post by AZJIO »

I would like to set a negative number when returning a pointer from a procedure on errors. Can I do that? I found no mention of this in the reference file.

The point is that if we interpret the pointer as a number, the high bit may be considered as a negative value of the number.
If there is no error I should get the actual pointer to use in the following functions.

Code: Select all

Procedure FuncName()
    Protected *m

    If x
        ProcedureReturn -1
    EndIf
    If y
        ProcedureReturn -2
    EndIf
    If z
        ProcedureReturn -3
    EndIf

    ProcedureReturn *m
EndProcedure

*m = FuncName()
If *m < 0
	Debug "Error"
	Select *m
		Case -1
			Debug "Error=1"
		Case -2
			Debug "Error=2"
		Case -3
			Debug "Error=3"
		Default
; 			...
	EndSelect
EndIf
User avatar
mk-soft
Always Here
Always Here
Posts: 6315
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Can a pointer be a negative number?

Post by mk-soft »

Maybe works, but I think it's programmed for unclean

Code: Select all


Prototype Invoke()

Procedure Func1()
  Debug "Function 1"
EndProcedure

Procedure Func2()
  Debug "Function 2"
EndProcedure

Procedure FuncName(Name.s, *Func.Integer)
  Protected *m
  
  If Not *Func
    ProcedureReturn -1
  EndIf
  If x
    ProcedureReturn -2
  EndIf
  If y
    ProcedureReturn -3
  EndIf
  If z
    ProcedureReturn -4
  EndIf
  ;
  Select Name
    Case "1"
      *Func\i = @Func1()
      
    Case "2"
      *Func\i = @Func2()
      
    Default
      ProcedureReturn -5
  EndSelect
  
  ProcedureReturn 0 ; Ok 
EndProcedure

Define function.Invoke

r1 = FuncName("2", @function)
If r1 
  Debug "Error=" + r1
Else
  function()	  
EndIf
Last edited by mk-soft on Sun Apr 20, 2025 7:05 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
NicTheQuick
Addict
Addict
Posts: 1527
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Can a pointer be a negative number?

Post by NicTheQuick »

Usually pointers are unsigned values. but depending on the programming language and available data types you can interpret them as negative values. Because of ASLR (Address Space Layout Randomization) you can in fact get negative values although you only use very less memory in your application.

But you can usually hide 2 bits in pointers if you assume that the pointers are always aligned. As you can see in this example the two lowest bits are always zero.

Code: Select all

Define s.s = "hi"
Define *p = AllocateMemory(4)
Procedure hi()
EndProcedure
DataSection
	hi:
	Data.i 0
EndDataSection

Debug Bin(@s)
Debug Bin(*p)
Debug Bin(@hi())
Debug Bin(?hi)
Okay, that's still a hack and maybe does not help you. So here's the best solution: Just use another parameter for additional return values of a function.

Code: Select all

Procedure FuncName(*ptr.Integer)
	Protected *m
	
	If Not *ptr
		ProcedureReturn 1
	EndIf
	If x
		ProcedureReturn 2
	EndIf
	If y
		ProcedureReturn 3
	EndIf
	If z
		ProcedureReturn 4
	EndIf
	
	*ptr\i = *m
	ProcedureReturn 0
EndProcedure

Define *m
error = FuncName(@*m)
If error
	Debug "Error"
	Select error
		Case 1
			Debug "Invalid argument"
		Case 2
			Debug "Error=2"
		Case 3
			Debug "Error=3"
		Case 4
			Debug "Error=4"
		Default
			; 			...
	EndSelect
EndIf
Last edited by NicTheQuick on Sun Apr 20, 2025 7:18 pm, edited 1 time in total.
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.
User avatar
mk-soft
Always Here
Always Here
Posts: 6315
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Can a pointer be a negative number?

Post by mk-soft »

With macOS I have already seen odd functions addresses!
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
AZJIO
Addict
Addict
Posts: 2223
Joined: Sun May 14, 2017 1:48 am

Re: Can a pointer be a negative number?

Post by AZJIO »

Then the old-fashioned analog of GetLastError()

Code: Select all

Global g_LastError

Procedure FuncName()
	Protected *m
	g_LastError = 0

	If x
		g_LastError = 1
        ProcedureReturn 0
    EndIf
    If y
		g_LastError = 2
        ProcedureReturn 0
    EndIf
    If z
		g_LastError = 3
        ProcedureReturn 0
    EndIf

    ProcedureReturn *m
EndProcedure

*m = FuncName()
If g_LastError
	Debug "Error"
	Select g_LastError
		Case 1
			Debug "Error=1"
		Case 2
			Debug "Error=2"
		Case 3
			Debug "Error=3"
	EndSelect
Else
	Debug *m
EndIf
User avatar
NicTheQuick
Addict
Addict
Posts: 1527
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Can a pointer be a negative number?

Post by NicTheQuick »

AZJIO wrote: Sun Apr 20, 2025 7:10 pm Then the old-fashioned analog of GetLastError()

Code: Select all

Global g_LastError

Procedure FuncName()
	Protected *m
	g_LastError = 0

	If x
		g_LastError = 1
        ProcedureReturn 0
    EndIf
    If y
		g_LastError = 2
        ProcedureReturn 0
    EndIf
    If z
		g_LastError = 3
        ProcedureReturn 0
    EndIf

    ProcedureReturn *m
EndProcedure

*m = FuncName()
If g_LastError
	Debug "Error"
	Select g_LastError
		Case 1
			Debug "Error=1"
		Case 2
			Debug "Error=2"
		Case 3
			Debug "Error=3"
	EndSelect
Else
	Debug *m
EndIf
...and if you want to have it Threadsafe you can just use `Threaded` instead of `Global`, which is also automatically global and it will result in one version of `g_LastError` per Thread.
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.
AZJIO
Addict
Addict
Posts: 2223
Joined: Sun May 14, 2017 1:48 am

Re: Can a pointer be a negative number?

Post by AZJIO »

I realized that if a number does not support negative numbers, then it will not take this form, for example:

Code: Select all

a.a = -1
Debug a.a
So my question was bound to fail.
User avatar
Demivec
Addict
Addict
Posts: 4281
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Can a pointer be a negative number?

Post by Demivec »

In PureBasic a pointer represents an unsigned address value but it is represented by a signed integer. This means the value can be negative.

You can select a special value or range of values to use as an error indicator. The value -1 can be used as a singular error indicator because its unsigned value is the highest possible memory location. You couldn't store more than a byte there so it wouldn't be the address of a structure, buffer, or procedure. Address zero is likewise a good error indicator.
Olli
Addict
Addict
Posts: 1258
Joined: Wed May 27, 2020 12:26 pm

Re: Can a pointer be a negative number?

Post by Olli »

(4-bits convention)
-> Signed value 0x0Fh will give -1
-> Unsigned value 0x0Fh will give 15

Pointer is an unsigned value : everything is positive, whatever the status of the most significant binary digit.

My suggest :

Code: Select all

Procedure exception1()
EndProcedure

Procedure exception2()
EndProcedure

Procedure exception3()
EndProcedure

Procedure exception4()
EndProcedure


 Procedure FuncName()
    Protected *m

    If x
        ProcedureReturn @exception1()
    EndIf
    If y
        ProcedureReturn @exception2()
    EndIf
    If z
        ProcedureReturn @exception3()
    EndIf

    ProcedureReturn *m
EndProcedure

*m = FuncName()
If *m < 0
	Debug "Error"
	Select *m
		Case @exception1()
			Debug "Error=1"
		Case @exception2()
			Debug "Error=2"
		Case @exception3()
			Debug "Error=3"
		Default
; 			...
	EndSelect
EndIf
ricardo_sdl
Enthusiast
Enthusiast
Posts: 141
Joined: Sat Sep 21, 2019 4:24 pm

Re: Can a pointer be a negative number?

Post by ricardo_sdl »

For pointers I always return #Null when something went wrong or it wasn't possible to return a valid pointer. If I need to know what what happenened I add an output parameter like this:

Code: Select all

Procedure GetFunc(Name.s, *ReturnError.Long)
  
  If Name = "name1"
    ProcedureReturn *p1
  ElseIf Name = "name2"
    ProcedureReturn *p2
  EndIf
  
  If error1
    *ReturnError\l = -1
  Else
    *ReturnError\l = -2
  EndIf
  
  ProcedureReturn #Null
  
  
  
EndProcedure
And then I call like this:

Code: Select all

Define Name.s = "invalid"
Define ReturnError.Long
Define *Func = GetFunc(Name, @ReturnError)
If *Func = #Null
  Debug ReturnError\l
EndIf
You can check my games at:
https://ricardo-sdl.itch.io/
Post Reply