This is embarrassing
This is embarrassing,
Do i need to create one TFormatSettings instance for each thread that needs it? If i want the same settings (for all threads), then creating one global record should suffice because it will only be /read/ by the format functions? I.e. using the global one from "treads-galore".
Another related question; i was able to get a screen copy of the list of functions that takes the AFormatSettings parameter by searching in the help. But that cannot be copied further and it's just a list anyway. Is there a warning i can turn on for all uses of overloaded non-thread safe formatting functions?
Yes, you guess right, sitting with some legacy stuff...
TIA,
/D
Do i need to create one TFormatSettings instance for each thread that needs it? If i want the same settings (for all threads), then creating one global record should suffice because it will only be /read/ by the format functions? I.e. using the global one from "treads-galore".
Another related question; i was able to get a screen copy of the list of functions that takes the AFormatSettings parameter by searching in the help. But that cannot be copied further and it's just a list anyway. Is there a warning i can turn on for all uses of overloaded non-thread safe formatting functions?
Yes, you guess right, sitting with some legacy stuff...
TIA,
/D
One shared global format settings instance is fine. So long as it is not mutated.
ReplyDeleteDavid Heffernan, thank you for the confirmation, exactly what i needed.
ReplyDeleteAnyone on the second question? I'd like a warning/hint for each use. All ye OTA fans? No-one?
ReplyDeleteI don't think it's OTA related and I am afraid the answer is no. Grep with regex should find them.
ReplyDeleteStefan Glienke, excellent! Spending 12 h on something deadpan is quite ok when you know that the gururs would have done the same. Thanks!
ReplyDeleteOh, if anyone think that came across as ironic, you're wrong.
ReplyDeleteI think the docs are missleading here because they warn on the format/conversion routines, like http://docwiki.embarcadero.com/Libraries/en/System.SysUtils.FloatToStr
ReplyDeleteI think the paragraph stating wether the functions are or not thread-safe brings FUD, because it's as David says, as long as you don't mutate the record, one global variable is enough. It's always the same issue on what "thread-safe" means
Sometimes Ctrl-Shift-Enter on TFormatSettings in the code editor gives you that list. Often it's incomplete.
ReplyDeleteAgustin Ortu, yes the docs are murky at the least. I can see (and some have confirmed) that a global TFormatSettings will do. The docs say that's why the first overload is not thread safe. What happens with the global instance? Does it change every now and then, that would be a reason. Maybe the un-thread-safeness is just when switching between daylight saving and back? See, i'm speculating. Where can i go to gain understanding?
ReplyDeleteDany Marmur if memory serves me right, it changes on a settings changed windows message. Since it's global, it is writable by any thread. I'm pretty sure it doesn't respond to some locale changes done through the windows API.
ReplyDeleteJeroen Wiert Pluimers good point
ReplyDeleteJeroen Wiert Pluimers yes that is completely logical. I was looking at the sources, but something else happened :)
ReplyDeleteRTL feature request:
var
lApp: TApplcation;
begin
LockDownGlobalFormatSettings := true;
ReportMemory...
MainFormOn...
ModalDialogHavoc...
...
Dany Marmur That feature already exists, set UpdateFormatSettings to False
ReplyDeleteStefan Glienke, thanks! Had no idea.
ReplyDeleteNeither did I. Searched for every place where FormatSettings was assigned and then searched for every place that routine was called and learned something new ;)
ReplyDeleteI did not search if any EMBT code sets any member of that global variable but I I am pretty sure that is not the case. Third party code might still do that though but that would clearly be a defect.
FormatSettings is a global. Vcl.Forms will ask windoze (i only target Win with Delphi) during initialization. The global Application object will lock it with a TMonitor.
ReplyDeleteThen, if you compile a "pure" service, it (Vcl.SvcMgr) will use the global Application object in Vcl.Forms to hook windows messages.
So i put your finding in my initialization section of a "high-level" unit. I can even change the globals setting there.
I'm happy now. Thanks again Stefan Glienke.
The help did not find the UpdateFormatSettings and i have not seen it in "Whats new" for as long as i can remember (D2006?).
This post would not have been if i started with the sources instead of the help files. The help has become better IMO the last years so i often try it to see if i can find what i'm looking for. Previously i Ctrl+Clicked and read the sources. Am going back there...
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Vcl.Forms.TApplication.UpdateFormatSettings
ReplyDeleteSearching for documentation. Some tips here: stackoverflow.com - How can I search for Delphi documentation?
ReplyDeleteStefan Glienke a lovely imperative verb for a property. I thought it was a method. Now I know what it is for.
ReplyDeleteNice use of the late last century Object Pascal Style Guide by Charlie Calvert: edn.embarcadero.com - Object Pascal Style Guide
Jeroen Wiert Pluimers Not a joke that naming things is one of the hardest things in software development.
ReplyDeleteI usually try to use modal verb prefixes for boolean properties (HasFoo, MustUpdateFoo, CanLoadFoo, ShouldDisplayFoo, etc)
Did some research: UpdateFormatSettings was introduced in D3. Documented since at least D2007. FormatSettings was introduced in XE and documented since XE2. Before that only global variables like DecimalChar.
ReplyDeleteJeroen Wiert Pluimers, cool. Imagine if all the formatting functions had the line "or you can set the global UpdateFormatSettings to false..." in the docs.
ReplyDelete