I just found in the documentation that FloatToStr
and DateToStr
are not thread-safe in their one-paramater overloads. The reason is that they access localization information stored in global variables.
My question is: is this of any practical relevance if I do not change the format settings at runtime? As far as I understand it, I'm on the safe side as long as everyone only reads the format settings - even from multiple threads.
Is that true or am I missing something here?
Thanks.
Local variables and parameters are always thread-safe. Instance variables, class variables, and global variables may not be thread-safe (but they might be). Nevertheless, threads and shared variables can be useful.
What is thread safety ? thread-safety or thread-safe code in Java refers to code that can safely be utilized or shared in concurrent or multi-threading environment and they will behave as expected.
Final variables are immutable references, so a variable declared final is safe to access from multiple threads. You can only read the variable, not write it.
FloatToStr, DateToStr and others similar functions are reading global format settings. So, if your application does not change these settings for these function calls, then it is thread safe. The following code on opposite is not thread safe:
DecimalSeparator := ',';
try
s := FloatToStr(123.45);
finally
DecimalSeparator := '.';
end;
When you need the tread safety and "local" format settings, then you have to use overloaded functions, which take as last parameter: AFormatSettings: TFormatSettings. So, to make above code thread safe you have to write:
var
fs: TFormatSettings;
GetLocaleFormatSettings(GetThreadLocale, fs);
fs.DecimalSeparator := ',';
s := FloatToStr(123.45, fs);
Notes:
Even the global settings can change when Application.UpdateFormatSettings (Delphi 7, don't know about Delphi XE) is True. When a user changes the Regional and Language options of Windows, this will be reflected in your application. You can circumvent this by setting UpdateFormatSettings to False, but even then you can't be sure, maybe there is some third party library you use that changes it.
I had some problems with our own application: Nowhere in our application the global formatsettings were changed, but still there was information loss because a float was converted to a string and when the string was converted back to float, the formatsettings were magically changed. (So you had this: 1.2 -> convert to string -> '1.2' -> black magic that changed formatsettings.decimalseparator -> convert to float -> 12).
My suggestion: only use the not thread-safe version for UI purposes so the user sees dates and floats the way he likes them to see, for everything else, use the thread-safe version. Conversions inside your application will then be consistent and don't give surprises.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With