Guest Posted January 12, 2021 1 minute ago, balabuev said: The initial user's code itself (without our additions) is correct and should work without any bugs or exceptions. I was writing and didn't see your post, the question can be simplified to this "is correct" coming from does work fine, but it is ensured by the language or the documentation ? or it does break the rule of string are not thread safe. Share this post Link to post
balabuev 102 Posted January 12, 2021 "is correct" means that even in current implementation it will (and should) work fine. And so, your new implementation should also not raise any exceptions. Share this post Link to post
Stefan Glienke 2002 Posted January 12, 2021 17 minutes ago, Kas Ob. said: i mean global strings are thread safe ? What is thread safety anyway? 1 Share this post Link to post
Guest Posted January 12, 2021 2 minutes ago, balabuev said: "is correct" means that even in current implementation it will (and should) work fine. And so, your new implementation should also not raise any exceptions. What is built on false is false, so that code is working fine because interlocked operation, but it is not sanctioned as correct code and should not be expected to be right or correct to begin with. So breaking compatibility due the code been built on wrong assumption is not big problem as it can be fixed by the developer by copy the string to local var inside the thread code, as it should be his responsibility not the compiler, the threading model and data integrity are the developer problem (responsibility) and his design not the Delphi compiler. Also i don't think breaking compatibility for the sake performance and fixing unseen leaks/bugs is bad decision, on contrary Delphi broke compatibility once with the transition from AnsiString, many if not all the applications back then suffered from this and even some still till now, but are we now in better place with better Delphi and strings ? Yes we are. Share this post Link to post
Guest Posted January 12, 2021 3 minutes ago, Stefan Glienke said: 20 minutes ago, Kas Ob. said: i mean global strings are thread safe ? What is thread safety anyway? My question should be ( in better English i hope) 🙂 Are stings thread safe? Also what do you think about this discussion ? is it a right to question the possibility of better strings-type-like by fixing the RTL and the compiler ? even if could lead to break in compatibility with different versions of the compiler and the RTL ? Share this post Link to post
balabuev 102 Posted January 12, 2021 So, then please argue, why this code is not correct. In which exact place. Share this post Link to post
Guest Posted January 12, 2021 Just now, balabuev said: So, then please argue, why this code is not correct. In which exact place. Two threads should not be accessing an integer with interlocked operation, so why it should be alright and correct to read a string by two concurrent threads ? (by accessing i know it will work fine with just reading an integer) If that behaviour is needed (reading string from multiple threads in concurrent) then the developer who wrote the thread code should copy the string first, then handle it, it is not the responsibility of the compiler or the RTL, unless it is documented behaviour. Share this post Link to post
Stefan Glienke 2002 Posted January 12, 2021 (edited) 15 minutes ago, Kas Ob. said: My question should be ( in better English i hope) 🙂 Are stings thread safe? Also what do you think about this discussion ? is it a right to question the possibility of better strings-type-like by fixing the RTL and the compiler ? even if could lead to break in compatibility with different versions of the compiler and the RTL ? The question stands - there is no "yes/no" about that - their reference count is threadsafe - an assignment is not because its not atomic (which is the very same issue that Dalija wrote about in her blog post). About this discussion I think it is nonsense - the issue being pointed out by Marco arises when you access something with a broader scope than where you are currently - i.e. a global variable or a variable outside of the current nested routine - that also includes passing the same variable by reference twice or more and modifying it. f(i,i) would also be defect if it was implemented like this: while a > 0 do begin Inc(b); Dec(a); end; "Better" for strings would raise the question: better for what? Memory consumption? UTF8, string interning. Multithreading? Immutability. Memory locality? Short string optimization (i.e. avoiding the memory indirection) - there are probably more and most of them would be a complete breaking change even more than Delphi 2009. Edited January 12, 2021 by Stefan Glienke 3 Share this post Link to post
balabuev 102 Posted January 12, 2021 var G: string; CriticalSection: ...; procedure TForm11.Button1Click(Sender: TObject); begin G := 7.ToString; // Init with non contant string data. for i := 0 to 1 do begin TTask.Run(procedure var localStr: string; begin CriticalSection.Asquire; // Fetch G into local variable under critical section protection. localStr := G; // CriticalSection.Release; // A(localStr); end); end; end; I claim, that even if we rewrite the code with critical section, it will still not work with your new implementation. Share this post Link to post
Guest Posted January 12, 2021 1 minute ago, balabuev said: I claim, that even if we rewrite the code with critical section, it will still not work with your new implementation. Critical sections are not required here, just special copy string which should touch RefCount of the string global one, could be a new RTL function. Share this post Link to post
Guest Posted January 12, 2021 16 minutes ago, Stefan Glienke said: About this discussion I think it is nonsense - the issue being pointed out by Marco arises when you access something with a broader scope than where you are currently - i.e. a global variable or a variable outside of the current nested routine - that also includes passing the same variable by reference twice or more and modifying it. f(i,i) would also be defect if it was implemented like this: while a > 0 do begin Inc(b); Dec(a); end; "Better" for strings would raise the question: better for what? Memory consumption? UTF8, string interning. Multithreading? Immutability. Memory locality? Short string optimization (i.e. avoiding the memory indirection) - there are probably more and most of them would be a complete breaking change even more than Delphi 2009. Nonsense, then lets stop it here. Share this post Link to post
balabuev 102 Posted January 12, 2021 (edited) agree 🙂 Edited January 12, 2021 by balabuev Share this post Link to post