String[index] inserts a null.
Re: String[index] inserts a null.
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.
#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.
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: String[index] inserts a null.
Yeah, that would probably be good. Hope you like Markdown...
Re: String[index] inserts a null.
Done (added my full synthesis with test code in final comment):
#577 - s = text . Inserting strings into an indexed string of U
#577 - s = text . Inserting strings into an indexed string of U
Re: String[index] inserts a null.
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
Re: String[index] inserts a null.
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 )
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.ZSTRING * 1
WSTRING * 1
Re: String[index] inserts a null.
- 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'?
- Only '*Strptr(s) = Asc("#")' should be allowed!
- Would this be different if 'typeof(*Strptr(s)) = ZSTRING'?
Re: String[index] inserts a null.
*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.
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.
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
Re: String[index] inserts a null.
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
*pz or pz for a zstring
(*pz) or pz[j] for an ubyte
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: String[index] inserts a null.
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.)
(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.)
Re: String[index] inserts a null.
In these expressions (Indexed zstring ptrs), the first '[]' does not represent the string index operator but the pointer index operator with as definition: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.
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)
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: String[index] inserts a null.
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).
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).
Re: String[index] inserts a null.
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!
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: String[index] inserts a null.
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.fxm wrote:In summary, both dereference by the same way a pointer with offset k, what is the difference?
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.
Re: String[index] inserts a null.
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())
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.
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]
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.
Re: String[index] inserts a null.
Bug report filled to keep track:
#674 Parentheses around 'Strptr()' are mandatory before applying operator '[]' (pointer index)
#674 Parentheses around 'Strptr()' are mandatory before applying operator '[]' (pointer index)