Page 2 of 2

Posted: Thu May 24, 2007 12:53 pm
by srod
That makes perfect sense and I can now see it in the assembly code - nice one detective inspector iNX! :)

I was looking for something the code was doing, rather than something it wasn't (if that makes any sense?) I should have spotted that.

Actually, looking a little deeper, it is clear that the calling code does not place the address of the string variable on the stack, but the address of the underlying character buffer. This means that the function has no chance of pointing the original string variable to any new buffer which is allocated. :)

Posted: Thu May 24, 2007 1:33 pm
by iNX
srod wrote: This means that the function has no chance of pointing the original string variable to any new buffer which is allocated. :)
This is a perfect summary of the matter.

In the end, we could say that passing a pointer to a string to a procedure can be considered safe only for reading the string contents, or for writing a fixed number of characters that we're sure will fit in the buffer (However i would avoid doing this).

Whenever the string contents must be changed from within the procedure with no limitations, the only solution, seems to pass a pointer to a structure of type .string, instead of a pointer to a string.

btw i checked also this case:

Code: Select all

Procedure ModString(*a.s)
  
  *a="2434567892434567892434767767677676" ; this screws things up
EndProcedure

x.s
y.s
x="ab"
y="cd"
ModString(@x)
Debug x
and the problem, at asm level, is exactly the same.

Posted: Thu May 24, 2007 2:33 pm
by Psychophanta
Hay guys,
@srod, i think you are wasting time and words because there is a clear big bug related with string pointers.
A pointer is a memory address, not a string of alfanumeric characters. 8) (NOTE that currently in PB *var.s is not a pointer for the programmer, it is not a memory adress, but a string of alfanumeric characters).
And here's is the best and fastest solution for it imho:
http://www.purebasic.fr/english/viewtopic.php?t=26326


@iNX, you have realized about it :wink:

Posted: Thu May 24, 2007 4:21 pm
by iNX
Psychophanta wrote: And here's is the best and fastest solution for it imho:
http://www.purebasic.fr/english/viewtopic.php?t=26326


@iNX, you have realized about it :wink:
I read carefully your solution and i've got a question. I understand your point from a theoretical point of view and i understand the various inconsistencies. I also understand your point about readability, even if, since purebasic doesn't allow automatic dereference, .l .b and so on are only useful for.. readability.
Anyway, if, as you suggest, .s was considered internally as .c what would the practical consequences be?
Would they be something like these things i wrote some posts above?
At this point, the use of *stringpointer="something" imho makes even less sense, and maybe should be prohibited, so that *stringpointers.s would be numeric and people would have to use Pokes to use them for writing.
Or would there be some other consequencies that i'm missing?

Posted: Thu May 24, 2007 6:24 pm
by srod
Psychophanta wrote:A pointer is a memory address, not a string of alfanumeric characters. 8) (NOTE that currently in PB *var.s is not a pointer for the programmer, it is not a memory adress, but a string of alfanumeric characters).
I know what a pointer is Psychophanta, I was just trying to work with what iNX was trying to do with .s etc. It's not something that I would ordinarily even attempt. In a sense a string variable is a pointer, a pointer to a character buffer.

Of course at the heart of his problem is the fact that the @ operator works slightly differently with string variables than it does with, say, variables of type long in that it is made to return the address of the underlying character buffer and not the location which would be regarded as the true address of the string variable.

Posted: Thu May 24, 2007 10:11 pm
by Psychophanta
iNX wrote:
Psychophanta wrote: And here's is the best and fastest solution for it imho:
http://www.purebasic.fr/english/viewtopic.php?t=26326


@iNX, you have realized about it :wink:
I read carefully your solution and i've got a question. I understand your point from a theoretical point of view and i understand the various inconsistencies. I also understand your point about readability, even if, since purebasic doesn't allow automatic dereference, .l .b and so on are only useful for.. readability.
Anyway, if, as you suggest, .s was considered internally as .c what would the practical consequences be?
Would they be something like these things i wrote some posts above?
At this point, the use of *stringpointer="something" imho makes even less sense, and maybe should be prohibited, so that *stringpointers.s would be numeric and people would have to use Pokes to use them for writing.
Or would there be some other consequencies that i'm missing?
I will answer those questions:
I didn't say .s considered as .c, but *anyvar.s considered internally as *anyvar.c. Why? Exactly for this what you wrote:
At this point, the use of *stringpointer="something" imho makes even less sense, and maybe should be prohibited, so that *stringpointers.s would be numeric and people would have to use Pokes to use them for writing.
8)

@srod, not sure, but i still think the problem is farer than you seem to see now. You know what is a pointer, i know you know, and yes, a string var is internally a pointer. Well, the matter is that imho any * prefixed variable must contain a number, i.e. a pointer for the programmer, but never a string (i.e. an internally treated pointer).

Posted: Thu May 24, 2007 10:52 pm
by srod
The truth is, that I don't really see a problem, so in that respect you are correct. Pointers in Purebasic work the way they are documented. Sure it's not the same as languages like c and, in my opinion, PB is all the better for it where pointers are concerned. I'm not even convinced about the .s problem really as I can't recall ever reading (correct me if I'm wrong by all means) anything from Fred to indicate that the pointers should work any differently in this respect.

The fact that you can code *ptr.s = "Hello" and apparently end up with a string variable, rather than a pointer, is a little odd - perhaps a bug; but it doesn't detract from the fact that the pointers (when used with structures such as .STRING) work as documented. In most other circumstances I treat them no differently than regular 32-bit variables (the *.s peculiarity aside!)

Posted: Fri May 25, 2007 9:41 am
by iNX
Thank you guys for your attention and help.
I had started this topic because i needed a procedure to change multiple string variables passed as arguments, and i was wondering which was the best way to do it and whether there were multiple ways.
Now things are much clearer and we've also pointed out again a few inconsistencies that had already been discovered in other threads.

I agree with srod that these inconsistencies/bugs are easily superable and don't prevent from doing anything with strings and pointers.

At the same time, it's also true that they should be resolved because they could generate confusion, doubts and even lead to errors, as we've seen in this thread.

We'll wait and see.. :wink:

Posted: Fri May 25, 2007 4:10 pm
by Kale
Psychophanta wrote:A pointer is a memory address, not a string of alfanumeric characters
Actually a pointer is a variable that holds a memory address. :wink:

Posted: Fri May 25, 2007 4:22 pm
by Psychophanta
Kale wrote:
Psychophanta wrote:A pointer is a memory address, not a string of alfanumeric characters
Actually a pointer is a variable that holds a memory address. :wink:
Very true! :wink:

Posted: Fri May 25, 2007 7:40 pm
by Dr. Dri
Thanks to this topic I've learned something about string pointers.
Here is a code to sum up how to modify static/dynamic strings :

Code: Select all

Procedure ModString(*sa.s)
  PokeS(@*sa, "123456789")
EndProcedure

sp1.s
sp1 = "purebasic"

sp2.s
sp2 = "purebasic"

ModString(@sp2)

Debug sp2

ModString(@"purebasic")

Debug "purebasic"

Debug sp1
Dri

Posted: Fri May 25, 2007 9:04 pm
by srod
Dri, forgive me for asking, -and no offence intended, but are you serious here?

Quite aside from what you're doing to the static string (which should really be caught by the compiler imo), I suspect that using PokeS() directly into string variables will cause a memory leak as I wouldn't have thought that the original string would have been freed.

Also, the code could at best overwrite memory (as in the following) or could just as easily easily crash:

Code: Select all

Procedure ModString(*sa.s) 
  PokeS(@*sa, "123456789ssssssssssssssssssssssssssssssss") 
EndProcedure 

x.s 
x = "purebasic" 
y.s="Hello"
ModString(@x) 

Debug x 
Debug y  ;WRONG STRING DISPLAYED!!!

Posted: Sat May 26, 2007 6:03 pm
by Dr. Dri
modifying static strings is a matter that have already been discussed
and PokeS is unchecked (just like others memory functions)

It's just that i realized *pointer.s could be used this way!

Dri :)