Unexpected String behavior

General FreeBASIC programming questions.
Post Reply
azbluevw
Posts: 16
Joined: Dec 31, 2011 21:54

Unexpected String behavior

Post by azbluevw »

I had a program acting oddly and this is the simplest code I was able to create that replicates the problem (compiling with -lang qb):

Code: Select all

Option ByVal

declare sub more(s as string)

more("Less")
more("More")
end


sub more(s as string)
s = s+" is " + s
print s
end sub
I would expect to see:
Less is Less
More is More
Instead I see:
Less is Less
Less is Less
It seems that the second call to more() doesn't update the string s with its new value. If I create a new variable to hold the bigger string:

Code: Select all

sub more(s as string)
k$ = s+" is " + s
print k$
end sub
it works as expected. Same if I get rid of Option ByVal or compile without -lang qb (which doesn't allow for Option ByVal)

I assume there is some logical behavior I'm not understanding; briefly looking over the documentation for strings nothing jumped out at me. Does anyone have a better understanding of this?
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Unexpected String behavior

Post by fxm »

I can't seem to reproduce this bad behavior that you observe with 'Option ByVal' and '-lang qb'.
What version of fbc are you using?
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Unexpected String behavior

Post by counting_pine »

Yeah, it sounds like maybe an old version problem. 'byval as string' used to do something much less intuitive.
In this case, I suspect the "More" constant string data is probably being overwritten in memory when "is Less" is appended to "Less".

Code: Select all

String data: 0 1 2 3  4 5 6 7  8 9 a b  c d e f
Before:      L e s s \0 . . .  M o r e \0 . . .
After:       L e s s  . i s .  L e s s \0 . . .
I suggest passing s by reference. This should work the same in any dialect, without relying on an Option Byval:

Code: Select all

declare sub more(byref s as string)

more("Less")
more("More")
end


sub more(byref s as string)
s = s+" is " + s
print s
end sub
(Probably if you upgrade your FreeBASIC, then you could use byval instead.)
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Unexpected String behavior

Post by fxm »

Indeed, in older versions of fbc (before 1.00), 'byval as string' was converted to 'byref as zstring' by the compiler:

Code: Select all

declare sub more(byref z as zstring)

more("Less")
more("More")
end


sub more(byref z as zstring)
    z = z + " is " + z
    print z
end sub
Less is Less
Less is Less
Note:
Under the hood, 'byref as zstring' is processed through a 'byval as zstring ptr' with an automatic internal referencing/dereferencing by the compiler:

Code: Select all

declare sub more(byval p as zstring ptr)

more(@"Less")
more(@"More")
end


sub more(byval p as zstring ptr)
    *p = *p + " is " + *p
    print *p
end sub
Less is Less
Less is Less
Post Reply