Page 1 of 2

Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 12:20 am
by luis
WHAT:

I would like the ability to add a integer value to a pointer in a expression and assign a new value to the resulting address of the pointer expression and/or the ability to use [index] (like in C) as an offset to the base pointer address.

WHY:

As the things works now, you have to modify the value of the pointer var every time. It's a pain because this alter the pointer, so if you don't want that you have to save the original pointer to restore it later, or use another pointer var of the same type, copy the value of the original pointer to it, and then alter the copy.

Thanks.

PS: we talked about it a little hijacking Danilo's thread here -> http://www.purebasic.fr/english/viewtop ... =3&t=48198

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 12:24 am
by Shield
+#inf :D

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 12:41 am
by STARGĂ…TE
you can use it in PB like this:

Code: Select all

Structure Buffer
	b.b[0]
EndStructure

*Buffer.Buffer = AllocateMemory(100)

PokeL(@*Buffer\b[8], 123)
PokeL(@*Buffer\b[60], 987)

ShowMemoryViewer(*Buffer, 100)

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 1:07 am
by luis
That's even more painful :wink:

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 1:11 am
by skywalk
Yes, thanks to STARGATE and Demivec and others, I use this a lot.
It should be in the manual somewhere.

Code: Select all

Structure ScanPBDataTypes
  ; These take up no memory and are allowed to grow without redim
  ; when the structure is pointed at a memory buffer. 
  ; ex. *buf\d[i] ; 'i' being incremented in a loop
  b.b[0]  ; byte
  w.w[0]  ; word
  l.l[0]  ; long
  i.i[0]  ; integer
  q.q[0]  ; quad
  f.f[0]  ; float
  d.d[0]  ; double
  a.a[0]  ; ascii
  c.c[0]  ; character
  u.u[0]  ; unicode
  s.s[0]  ; string
EndStructure

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 1:28 am
by Shield
This is a very dirty way actually...I mean just from a logical / syntactical perspective,
it doesn't make sense to have a static array with a length of 0. It's as it wasn't even there (check out SizeOf).
And more importantly, since this is not documented that means it isn't official,
you never know when it stops working. :wink:

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 12:14 pm
by luis
@shield

I believe the primary reason for that was the use of Windows API.
There are a lot of functions in winapi needing a declaration of that type for some of the parameters.
So it's not something that is going away in next PB version.

The debugger is also tailored to not complain to the index out of bounds error for such arrays.

I used the [0] trick many times, and has its place and usefulness, and I know using wrapping structures you can sometime override a PB limit of some kind, but the request in the first post still stands, I would like the language to support it without the need to hacking my way through it. It can become cumbersome very quickly and I don't like to declare a structure every time I need a simple pointer.

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 5:07 pm
by buddymatkona
luis said: I would like the ability to add a integer value to a pointer in a expression and assign a new value to the resulting address of the pointer expression
I agree a normal assignment instead of Poke would be easier but at least you do not need a structure and *Ptr1 never changes. :)

Code: Select all

Dim Array.f(10)
For i = 0 To 9 : Array(i) = i : Next

*Ptr1 = @array()
For i = 0 To 9
  Debug Array(i) : PokeF(*Ptr1 + (i*SizeOf(float)),i+100) : Debug Array(i)
Next

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 5:26 pm
by wilbert

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 9:05 pm
by luis
@buddymatkona

Yes, with Poke?() you can use the expressions, it's handy and easy to use, but it's less efficient than using pointers arithmetic directly. Sometime it's irrelevant but sometimes it's not.

@wilbert

That would be the C way, but considering in PB the * is merged to the var name to denote its type (this var is and will always be a pointer), I doubt we will ever see something like that. And having both (suppose to use another char) will increment the suicide rate inside the community. I think.

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 9:35 pm
by skywalk
Am I missing something here :?:
It can't be easier than this...And what's wrong with using structures instead of Poke?

Code: Select all

EnableExplicit
;-{ STRUCTURES
Structure ScanPBDataTypes
  ; These take up no memory and are allowed to grow without redim
  ; when the structure is pointed at a memory buffer.
  ; ex. *buf\d[i] ; 'i' being incremented in a loop
  b.b[0]  ; byte
  w.w[0]  ; word
  l.l[0]  ; long
  i.i[0]  ; integer
  q.q[0]  ; quad
  f.f[0]  ; float
  d.d[0]  ; double
  a.a[0]  ; ascii
  c.c[0]  ; character
  u.u[0]  ; unicode
  s.s[0]  ; string
EndStructure
;-}
Define.i i,j
Define *buf.ScanPBDataTypes = AllocateMemory(255)
For i=0 To 31
  *buf\b[i] = i
Next i
ShowMemoryViewer(*buf, 255)
MessageRequester("Pause to review the memory...","")
i=0
j=Random(31)
*buf\b[i+j] = -127
ShowMemoryViewer(*buf, 255)
MessageRequester("Pause to review the memory...","Element " + Str(j)+" is now changed.")

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 10:22 pm
by PMV
It is a cosmetic improvement, much better to read. Thats why it would be
good to have that. The zero-static-structure-array is good to have and
it is per design not to be changed in any future version until static-arrays
inside of structures are completely changed. And that would break any
"normal" code, too. So that is not the problem.

This request is to get a well documented and easy to read pointer-
arithmetic improvement. Nothing more and nothing less. :wink:

MFG PMV

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 10:29 pm
by luis
@skywalk
myself wrote: I know using wrapping structures you can sometime override a PB limit of some kind, but the request in the first post still stands, I would like the language to support it without the need to hacking my way through it.
something like this

Code: Select all


Structure T_TEST
 a.i
 b.i
 c.i
 arr.i[32]
EndStructure

*ptr.T_TEST = AllocateMemory(SizeOf(T_TEST) * 10)
*save = *ptr

For k = 0 To 9
    *ptr\a = k
    *ptr\b = k
    *ptr\c = k
    *ptr\arr[10] = k
    *ptr\arr[20] = k
    
    *ptr + SizeOf(T_TEST)
Next

*ptr = *save

ShowMemoryViewer(*ptr, SizeOf(T_TEST) * 10)

using the [0] wrapper trick become this (if I'm wrong please correct me) :

Code: Select all

Structure T_TEST
 a.i
 b.i
 c.i
 arr.i[32]
EndStructure

Structure T_TEST_WRAP
 s.T_TEST[0]
EndStructure


*ptr.T_TEST_WRAP = AllocateMemory(SizeOf(T_TEST) * 10)

For k = 0 To 9
    *ptr\s[k]\a = k
    *ptr\s[k]\b = k
    *ptr\s[k]\c = k
    *ptr\s[k]\arr[10] = k
    *ptr\s[k]\arr[20] = k        
Next

ShowMemoryViewer(*ptr, SizeOf(T_TEST) * 10)

The problems with the above:

1) I don't like the fact I have to define a wrapper structure that has no reason to exists, as it's there only as a clumsy workaround because pb pointers don't allow what I'm asking in the first post.

2) I don't like the fact that when I allocate the memory buffer it has to be assigned to a var that it's not of the real type I would like to work with.

3) I don't like to have to write

*ptr\s[k]\a = k

with that \s inside which has nothing to do with what I was trying to accomplish and it just obfuscate the code

All this is a workaround, it add useless references to something not needed and makes you ask: "what is this ?" when you look at your code later, hence the request.

In the first code I don't like to have to save the pointer, but the rest is ok and it's just clear.

I can live without it, but I thought to ask for it !

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 11:24 pm
by skywalk
I was only griping about not needing Poke() in this case.
I am always in favor of improvements in readability.
Like the addition of more default parameters :wink:
FindString(x$,y$,[,StartPosition]) :!:

However, I do think this is more difficult to implement.
How does the compiler differentiate various degrees of ?
*x = 2 + 2
*x + 2 = 2

And I do prefer the existing [0] static structure method be documented in the manual. :(

Re: Pointer arithmetic (expressions with integers)

Posted: Wed Nov 16, 2011 11:42 pm
by luis
skywalk wrote: How does the compiler differentiate various degrees of ?
*x = 2 + 2
*x + 2 = 2
Not using the [] syntax it could be:

*x = 2 + 2 ; assign 4 to the pointer var (as today)

*x + 2 = 2 ; meaningless (as today), would be nice a syntax error

*x\datatype = 2 + 2 ; write 4 to the memory area pointed by the pointer (as today)


what we don't have

(*x + 2)\dataytype = 2
write 2 to the memory area pointed by the pointer incremented by two
or
write 2 to the memory area pointed by the pointer incremented by 2 times the size of datatype (*)

using []
*x[2]\datatype = 2
write 2 to the memory area pointed by the pointer incremented by 2 times the size of datatype

(*) It should be decided if to use the datatype size or not in the case of the address + integer expression, maybe it could be more versatile using a simple addition of bytes in that case, and using the actual data size only with [].