Search code examples
multithreadingdelphithread-safetydelphi-xe

Thread-Safeness of FloatToStr / DateToStr


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.


Solution

  • 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:

    1. GetLocaleFormatSettings and fs initialization may be called once and then fs may be used multiple times. This will speedup the code.
    2. Instead of GetLocaleFormatSettings may be used TFormatSettings.Create. I am not sure when that was introduced, but I see that in Delphi XE.