String[index] inserts a null.

General FreeBASIC programming questions.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

I had only added some comments to bug report of Richard (but not my full synthesis above):
#577 - s = text . Inserting strings into an indexed string of U

If necessary, I can add my above synthesis as a final comment to this bug report.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: String[index] inserts a null.

Post by counting_pine »

Yeah, that would probably be good. Hope you like Markdown...
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

Done (added my full synthesis with test code in final comment):
#577 - s = text . Inserting strings into an indexed string of U
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

After the fix, it remains some weird thing!

Code: Select all

Dim As String s = "test string"

Print *Strptr(s)
Print Len(*Strptr(s))
#print typeof(*Strptr(s))

*Strptr(s) = Asc("#")
Print *Strptr(s)
Sleep

Code: Select all

Compiler output:
ZSTRING * 1

Code: Select all

test string
 11
#est string
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: String[index] inserts a null.

Post by dkl »

Are you referring to the #print typeof() output?

Code: Select all

dim as zstring ptr z
dim as wstring ptr w
#print typeof( *z )
#print typeof( *w )
ZSTRING * 1
WSTRING * 1
The compiler cannot know the true length of the dereferenced strings at compile-time, so reporting a length of 1 character seems like a good fall-back to me. Ideally it would report just "ZSTRING" and "WSTRING", without a guessed length. See also #650.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

- Is it because 'typeof(*Strptr(s)) = ZSTRING * 1' that '*Strptr(s) = Asc("#")' is allowed by the compiler (that I consider as a bug)?
- Only '*Strptr(s) = Asc("#")' should be allowed!
- Would this be different if 'typeof(*Strptr(s)) = ZSTRING'?
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: String[index] inserts a null.

Post by dkl »

*Strptr(s) = Asc("#") is allowed because Strptr(s) returns a ZSTRING PTR, dereferencing it can give a "ZSTRING" string or a "UBYTE" character, depending on the other operand. Here the other operand is Asc("#"), that is an integer, so *Strptr(s) will be treated as reference to the first character (it's the same as (Strptr(s))[0]). It's basically a short-cut version of string indexing.

Code: Select all

dim as zstring * 32 z = "hello"
dim as zstring ptr pz = @z

print z

'' Set first character
*pz = asc( "#" )
print z

'' Copy string data
*pz = "abcde"
print z

'' Set first character
pz[0] = asc( "#" )
print z

'' Set second character
pz[1] = asc( "#" )
print z
All this is related to the foo[N] pointer indexing operators being the same as *(foo + N), where + N can be omitted if N = 0.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

As for me, I will prefer always to use (pz as zstring ptr):
*pz or pz for a zstring
(*pz) or pz[j] for an ubyte
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: String[index] inserts a null.

Post by counting_pine »

I didn't know this was the case. I think I'd always assumed that a dereferenced zstring ptr is a zstring, and an indexed zstring is a ubyte.
(Indexed zstring ptrs don't fit well into this understanding, because the indexing syntax looks too much like you're expecting single character, or at least something indexable, while the normal rules of dereferencing imply a zstring.)
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

counting_pine wrote:Indexed zstring ptrs don't fit well into this understanding, because the indexing syntax looks too much like you're expecting single character, or at least something indexable, while the normal rules of dereferencing imply a zstring.
In these expressions (Indexed zstring ptrs), the first '[]' does not represent the string index operator but the pointer index operator with as definition:
p = *(p + i)

So, 'pz = *(pz + i)' and 'pz[j] = *(pz + i)[j]', where '*(pz + i)' well represents a zstring.
(in 'pz[j]', the first '[]' represents the pointer index operator and the second '[]' the string index operator)
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: String[index] inserts a null.

Post by counting_pine »

Of course. But to be honest, I think pz should be disallowed or discouraged, because indexing is only an intuitive operation when you expect different indices to access different objects, but the indexing operator here gives you different subsets of a single object.

It's not intuitive that pz gives you (roughly speaking) mid(*pz, i+1). If you really want to do *(pz + i), it's clearer just to write that.

I think the most likely use case of pz is probably going to be people expecting it to do the same as (*pz). Therefore I think a case could be made for disallowing it completely in order to prevent this confusion occurring.

An alternative would be to make it do the same thing as (*pz), but this obviously breaks the convention of p = *(p+i).
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

counting_pine wrote:It's not intuitive that pz gives you (roughly speaking) mid(*pz, i+1). If you really want to do *(pz + i), it's clearer just to write that.

pi as integer ptr
pz as zstring ptr

pi[k] dereferences an integer ptr with offset k, returning a reference to the integer at offset k
pr[k] dereferences a zstring ptr with offset k, returning a reference to the zstring at offset k

In summary, both dereference by the same way a pointer with offset k, what is the difference?


counting_pine wrote:An alternative would be to make it do the same thing as (*pz), but this obviously breaks the convention of p = *(p+i).

No, no, no please!
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: String[index] inserts a null.

Post by counting_pine »

fxm wrote:In summary, both dereference by the same way a pointer with offset k, what is the difference?
The difference is that an integer has a fixed size, and indexing into it is the same, in principle as indexing into an array of integers.
But pz doesn't work like this, and goes against the spirit of normal indexing operators.

I mean sure, the behaviour is "logical", according to the rules of dereferencing, but it's far from clear or intuitive if you glance at it in code.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

Weird

Example of syntaxes to extract a sub-string from a string, using 3 different zstring pointers:
- a variable: Pz1
- a function result: Pz2()
- an operator result: Strptr())

Code: Select all

Dim S As String = "He says: Hello FreeBASIC!"

Dim Pz1 As Zstring Ptr = Strptr(S)

Function Pz2 (Byref S As String) As Zstring Ptr
  Return Strptr(S)
End Function

Print S
Print *Pz1
Print *Pz2(S)
Print *Strptr(S)
Print
Print *@S[9]
Print
Print *(Pz1+9)
Print *(Pz2(S)+9)
Print *(Strptr(s)+9)
Print Pz1[9]
Print Pz2(S)[9] ' OK
'Print Strptr(S)[9] ' error 3: Expected End-of-Line, found '[' in 'Print Strptr(S)[9]
Print (Strptr(S))[9]
Why the parentheses are mandatory in the last line around the 'Strptr()' operator, while there are not mandatory in the penultimate line around the 'Pz2()' function?
For the parser, is there a processing difference between an operator and a function, each one returning a zstring pointer (by value) that is then dereferenced?
The operator STRPTR (String pointer) is there a real operator?

Same behavior with 'Sadd()' that is declared as 'function overload' in documentation.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: String[index] inserts a null.

Post by fxm »

Post Reply