Page 1 of 2
Posted: Thu Apr 10, 2003 4:35 pm
by BackupUser
Restored from previous forum. Originally posted by dmoc.
Can anyone explain the result of the follow...
Code: Select all
Dim a(10)
Global *ap.l
Debug "p: "+Str(ap)
Debug "d: "+Str(*ap)
Debug ""
ap = @a(3)
Debug "p: "+Str(ap)
Debug "d: "+Str(*ap)
Debug ""
*ap = 10
Debug "p: "+Str(ap)
Debug "d: "+Str(*ap)
Debug ""
Debug "0 - "+Str(@a(0))+": "+Str(a(0))
Debug "1 - "+Str(@a(1))+": "+Str(a(1))
Debug "2 - "+Str(@a(2))+": "+Str(a(2))
Debug "3 - "+Str(@a(3))+": "+Str(a(3))
Debug "4 - "+Str(@a(4))+": "+Str(a(4))
Debug "5 - "+Str(@a(5))+": "+Str(a(5))
Posted: Thu Apr 10, 2003 5:14 pm
by BackupUser
Restored from previous forum. Originally posted by Pupil.
What you must know is that 'ap' and '*ap' is two different variables, which means that *ap is not the pointer to ap. For pointer to be interesting you really have to work with structures. If you want *ap to point to the content of variable ap you can do this:
Code: Select all
*ap = @ap
ap = 20
debug "ap: "+str(ap)
debug "*ap: "+str(*ap)+" (this is the address to the variable ap)"
; Use a structure
structure longtype
long.l
endstructure
*bp.longtype = @ap
debug "ap: "+str(ap)
debug "*bp: "+str(*bp)
debug "*bp\long: "+str(*bp\long)
Hope this helps a little, i think soeone wrote a little tutorial about pointers, take a look at the resource site it might be there...
Posted: Thu Apr 10, 2003 5:58 pm
by BackupUser
Restored from previous forum. Originally posted by dmoc.
ok, thanks.
Posted: Sat Apr 26, 2003 8:52 pm
by Amiga5k
Indeed, pointers and structures are probably the two most difficult things to get a handle on (pun intended)
I was thinking that maybe it would be easier to visualize if instead of adding '*' to the beginning of a pointer variable, we could optionally put .p at the end - You wouldn't be able to put a basic data type there, but that wouldn't matter, because pointers should always be long anyways, right?
So memory.p would be the same as *memory.l
Too confusing?

Maybe we should just keep it the way it is...
Russell
Posted: Sun Apr 27, 2003 3:52 am
by Inner

They got me a gooden too when I started learning C, a friend spend a good 30mins trying to explain how they worked until in desperation and probably a bit of fustration he, pointed to my monitor with his finger and said "pointer"
Posted: Sun Apr 27, 2003 2:25 pm
by tinman
Amiga5k wrote:I was thinking that maybe it would be easier to visualize if instead of adding '*' to the beginning of a pointer variable, we could optionally put .p at the end
That would make it more difficult surely as you would not need to append the .p when using it and would therefore never know something was a pointer or not.
Amiga5k wrote:You wouldn't be able to put a basic data type there, but that wouldn't matter, because pointers should always be long anyways, right?
The type you append to a pointer determines what it points to. If they were always kept to a long, you would not be able to access something from inside whatever you point to.
Posted: Sun Apr 27, 2003 8:39 pm
by Amiga5k
Hmm... That's odd. I thought pointers were addresses of variables, procedures, etc.

If so, then surely it would have to be a long? There would be no need to have it any other data type since a long can represent the address of anything in memory, no?
I get your point about the optional .p, though. You'd have to commit yourself to putting a 'p' on the front of the variable so you'd remember what it is (should be doing this with all types, really).
Russell
Wait

Just found this in the help file:
To use a pointer, put * before the variable name. A pointer is a long variable which stores an address.
In the example, '*MyScreen.Screen = OpenScreen(0,320,200,8,0)' is used, so I see your point. I guess it was done this way to shorten the number of commands necessary to assign a pointer value? The syntax is slightly different from other languages that use pointers.
Posted: Mon Apr 28, 2003 8:47 am
by tinman
Amiga5k wrote:Hmm... That's odd. I thought pointers were addresses of variables, procedures, etc. :? If so, then surely it would have to be a long? There would be no need to have it any other data type since a long can represent the address of anything in memory, no?
That is correct, but...
Amiga5k wrote:
Wait :!: Just found this in the help file:
To use a pointer, put * before the variable name. A pointer is a long variable which stores an address.
In the example, '*MyScreen.Screen = OpenScreen(0,320,200,8,0)' is used, so I see your point. I guess it was done this way to shorten the number of commands necessary to assign a pointer value? The syntax is slightly different from other languages that use pointers.
If pointers could only be long types then you could not do this:
Structure MyStruct
a.w
b.l
EndStructure
*foo.MyStruct = some_address
Debug *foo\a
You would not be able to access items within structures from pointers if they were always longs. The internal representation of a pointer is indeed a long in that you use 32 bits to represent an address (on the systems that PB works on - pointers on other systems could easily be 16 or 64 bits). But the pointer type is usually referring to the type of structure that it points to, not the number of bytes that are used to store an address.
The syntax isn't much different from languages I've used, so I guess we've just used different languages :)
Posted: Tue Apr 29, 2003 10:50 pm
by Amiga5k
Code: Select all
Structure MyStruct
a.w
b.l
End Structure
*foo = @TheStruct.MyStruct
Debug *foo\a
The problem for me is that by attaching the 'pointed to' type to the pointer, it could appear as though it is actually that type, not a pointer. For example:
test.l = 9999999 ; This test is a long
*test.b = @source.b ; So is this one really, but it points to a byte.
test.b = 127 ; This one is a byte, but it sure looks like that other one!
Now, since the .b after *test is not necessary after it is initialized one could easily forget what type it points to. I'm sure PB sets the pointer type based on what it's pointing to, rather than what we tell it we're pointing to. That is, if I say:
test.b = 127
*newtest.w = @test
I would hope this would generate an error, although if the .w was optional PB could get the type by examining what we're actually assigning it from:
test.b = 127
*newtest = @test
Now PB looks at the @test part and determines that it is a byte. I can only think of one reason that the type suffix on the pointer would be necessary, and that is code clarity (programmer discipline - like forcing declares, etc). PB knows what it's pointing to, and we do too, because we assigned it!
Anyway, if I increment a word pointer by one, does it increment the actual address by two, since it is a word pointer? That would be handy, but potentially slow or dangerous if it's on an odd byte boundary to begin with.
Russell
Posted: Tue Apr 29, 2003 11:24 pm
by tinman
Amiga5k wrote:The problem for me is that by attaching the 'pointed to' type to the pointer, it could appear as though it is actually that type, not a pointer. For
Yep, but that is the risk you run. If you know the PureBasic syntax you should not make that mistake. The * is there to help you (albeit easy to miss/omit).
Now, since the .b after *test is not necessary after it is initialized one could easily forget what type it points to.
Yes, and that is the same for most languages. Variable naming style helps here, as you mentioned before. You could also say that this is a flaw in PureBasic because it allows you to declare different types of variables with the same name, rather than just being a pointer thing.
I'm sure PB sets the pointer type based on what it's pointing to, rather than what we tell it we're pointing to. That is, if I say:
test.b = 127
*newtest.w = @test
I would hope this would generate an error, although if the .w was optional PB could get the type by examining what we're actually assigning it from:
test.b = 127
*newtest = @test
Nope. No errors, no automatic typing from what is being pointed to (the type it points to will come from the current default type, as set by DefType, or long by default).
Anyway, if I increment a word pointer by one, does it increment the actual address by two, since it is a word pointer? That would be handy, but potentially slow or dangerous if it's on an odd byte boundary to begin with.
Pointer maths in PureBasic always works on their numerical values, not what size of thing they point to (like C). I suggested a long time ago to allow SizeOf to work with the basic types (and also to allow you to put variable names into it) but I do not think it was ever changed.
Posted: Wed Apr 30, 2003 1:38 am
by Amiga5k
I guess it's just one of those things we have to learn to live with
Nothing major, but important to remember.
I remember when I bought the original Blitz Basic 2 for the Amiga (ok, I guess if it is '2' it's not the original, but you get my meaning...) I had a dickens of a time grasping the concept of NewTypes (structures), but it eventually just 'clicked'. I can't remember if BB2 had pointers or not, though. I do remember 'Amiga Mode', though, where multitasking would be turned off so your program had COMPLETE control over the system

DirectX\Ogl is not quite there yet, as far as 'taking over' the system.
Hey, maybe you know this: I know that if you open a system modal dialog, *all* operations stop until the user responds. I wonder if you could 'take over' the system by opening a system modal dialog and just executing your program until the user responds? This would be the wrong way to do it, I'm sure, but has anyone tried it?
There's also 'EnterCriticalSection()' , but I think it is not quite the same thing.
Russell
Posted: Wed Apr 30, 2003 2:29 am
by El_Choni
Maybe a bit offtopic, maybe not; I like PB's ability to cast arrays, the problem is that it only casts long or string arrays (because they are pointers, so long vars). If it could be possible to cast word and byte arrays, it would be perfect (in this matter, at least).
Bye,
Posted: Wed Apr 30, 2003 10:26 am
by tinman
Amiga5k wrote:I can't remember if BB2 had pointers or not, though.
Yes, it had pointers and used the same notation as PureBasic :)
Amiga5k wrote:I do remember 'Amiga Mode', though, where multitasking would be turned off so your program had COMPLETE control over the system :twisted: DirectX\Ogl is not quite there yet, as far as 'taking over' the system.
Other way around - Amiga mode was system friendly, Blitz mode took over the system.
Amiga5k wrote:Hey, maybe you know this: I know that if you open a system modal dialog, *all* operations stop until the user responds.
I think all user interface stuff stops (or more precisely, all user input stops apart from the modal dialog) rather than every other process and task stops.
Amiga5k wrote:There's also 'EnterCriticalSection()' , but I think it is not quite the same thing. :?:
Entering a critical section just means that no other threads in your application will be run, apart from the one which is in its critical section.
El_Choni wrote:cast arrays, the problem is that it only casts long or string arrays (because they are pointers, so long vars). If it could be possible to cast word and byte arrays, it would be perfect (in this matter, at least).
What do you mean? You can point to any type of array using the "zero byte array in a structure" method.
Structure bptr ; Currently does not work under PB3.61 though :)
b.b[0]
EndStructure
Dim foo.b(10)
*bar.bptr = @foo()
Or have I misunderstood?
Posted: Wed Apr 30, 2003 2:02 pm
by El_Choni
Run this example to see what I mean:
Code: Select all
Dim MyArray(10)
Dim *MyCastedArray(10)
*MyCastedArray() = MyArray()
MyArray(0) = 15
MyArray(1) = 20
Debug *MyCastedArray(0) ; shows 15, correct
Debug *MyCastedArray(1) ; shows 20, correct
But:
Code: Select all
Dim MyArray.w(10)
Dim *MyCastedArray.w(10)
*MyCastedArray() = MyArray()
MyArray(0) = 15
MyArray(1) = 20
Debug *MyCastedArray(0) ; shows 1310735, wrong
Debug *MyCastedArray(1) ; shows 0, wrong
Posted: Wed Apr 30, 2003 5:33 pm
by tinman
El_Choni wrote:Run this example to see what I mean:
Are you trying to access the first array through a pointer? If so, what you have done is not the correct way to do it.
What you have done is created an array of 10 pointer items, not a pointer to an array of 10 items. When you access *MyCastedArray in the second case you will always be accessing a long because each item is a pointer (long). It just works with longs and strings because they happen to be the same size as a pointer.
If you want to access an array via a pointer, the only (current) way is to use a structure with an embedded array, or to use a single pointer and move around / calculate the byte offset manually.