Open AXKuhta opened 1 year ago
You mixed the second diff (top is the "multi line" and bottom the "single line") (not a biggy, just wanted to mention)
- BBARRAY bbt_Arr=bbArraySlice("$",bbStringSplit((BBSTRING)brl_stream_ReadLine2((struct brl_stream_TStream_obj*)bbt_File),((BBString*)&_s1)),1,(bbStringSplit((BBSTRING)brl_stream_ReadLine2((struct brl_stream_TStream_obj*)bbt_File),((BBString*)&_s1)))->scales[0]);
+ BBARRAY bbt_Arr=bbStringSplit((BBSTRING)brl_stream_ReadLine2((struct brl_stream_TStream_obj*)bbt_File),((BBString*)&_s1));
+ bbt_Arr=bbArraySlice("$",bbt_Arr,1,(bbt_Arr)->scales[0]);
I also reformatted the output a bit so it is easier to see what is happening:
/* single line */
BBARRAY bbt_Arr=
bbArraySlice(
"$",
bbStringSplit(
(BBSTRING)brl_stream_ReadLine2(
(struct brl_stream_TStream_obj*)bbt_File
),
((BBString*)&_s1)),
1,
(bbStringSplit(
(BBSTRING)brl_stream_ReadLine2(
(struct brl_stream_TStream_obj*)bbt_File
),
((BBString*)&_s1))
)->scales[0]
);
/* multi line */
BBARRAY bbt_Arr=
bbStringSplit(
(BBSTRING)brl_stream_ReadLine2(
(struct brl_stream_TStream_obj*)bbt_File
),
((BBString*)&_s1)
);
bbt_Arr=
bbArraySlice(
"$",
bbt_Arr,
1,
(bbt_Arr)->scales[0]
);
My guess is, that tries to do things without a temporary variable - and thus is resolving this "what to split" two times. In this very case it does not work out as it is not a variable it reads but a method call - so the content changes "inbetween".
This thing might also introduce bugs in multi threaded environments (if the "string getter" locks/unlocks a mutex and thus allows modification inbetween the execution of this daisy-chain.
The issue is not Readline().Split()
but StringGetMethod()[arraySlice..]
with the emphasize on the lack of the "count" part in the slice.
arr[1..]
this will transform to
bbArraySlice(
"$",
bbt_Arr,
1,
(bbt_Arr)->scales[0]
);
You left out the right hand side of the slice, so it wants to slice till the end - to know what the end is, it will ask "->scales[0]" of the array. and as the above code does not have that array in a variable already ... it uses whatever is needed to get the "array" -> and thus leads to the double "bbsplit(readline)".
It might affect not just "array slicing". The issue might arise everywhere you can leave out information and it will have to read it from the object "used on" (for now I can only imagine array slicing but am not sure if other stuff exists too).
This is a more concentrated sample:
Framework BRL.StandardIO
Import BRL.Filesystem
Import Brl.Random
Function GetStringArray:String[]()
Local s:String[] = ["hello", "world", String(Rand(10000))]
Print "returning " + s[2]
Return s
End Function
Print GetStringArray()[2..][0]
Output will show that the method is called twice and thus resulting in different values:
returning 1747
returning 6406
6406
Even shorter:
SuperStrict
Framework BRL.StandardIO
Function GetString:String()
Print "GetString() called"
Return "Test"
End Function
Print GetString()[0..]
GetString() called
GetString() called
Test
Given a file test.txt that contains
This is a test string. Sentence 1. Sentence 2.
and the following program:The expected result is
Sentence 1
but in reality it prints nothing.Workaround:
Diffing working C code against broken C code reveals what appears to be the problem:
ReadLine(File).Split(".") gets executed twice!
BlitzMax version: BlitzMax_win32_0.129.3.45