Geoff Clare wrote:
> The current draft says:
>
> The returned string may be invalidated by a subsequent call to
> bind_textdomain_codeset(), bindtextdomain(), setlocale(), or
> textdomain() in the same process, or a subsequent call to
> uselocale() in the same thread, except for calls that only query
> values.
>
> [...]
>
> > I think that specifying gettext() to be so restricted is not useful.
> > It would make more sense to allow concurrent uselocale() calls.
>
> The current draft text allows concurrent uselocale() calls.
This is better; thanks. Still, I don't think it is sufficient nor consistent.
OBJECTION 1:
It requires applications to delegate some calls to separate threads.
For example, take an application that regularly updates some UI and
also occasionally writes an JSON file.
For the UI updates, it will need to call gettext(). Let's assume that
the UI caches the string the strings that the application passes it,
e.g. for fast rerendering. This is the typical way a UI is built. E.g.
Gtk+: label1 = gtk_label_new (gettext ("Hello, world!"));
Qt: label1 = new QLabel (gettext ("Hello, world!"), panel);
For writing data in JSON format [1], it needs to convert
- strings to UTF-8 encoding,
- numbers to decimal representation, with '.' as decimal separator.
For converting numbers to decimal, since the standard has strtod()
but no strtod_l() [2], the most immediate implementation is to use
uselocale() with a "C" locale argument, then call strtod(), then
switch back to the previous locale using uselocale().
With the current wording, converting a number to decimal like this
will invalidate many of the strings that the UI is holding.
Thus, the application will need to move its JSON file writing to a
separate thread. This is a big architectural requirement.
OBJECTION 2:
It is inconsistent with other parts of POSIX. For localeconv() [3]
the wording is
"... might be overwritten by subsequent calls to setlocale() with the
categories LC_ALL, LC_MONETARY, or LC_NUMERIC, or by calls to
uselocale() which change the categories LC_MONETARY or LC_NUMERIC."
To make things consistent, you would need to change the text for gettext
from
"call to uselocale() in the same thread"
to
"call to uselocale() in the same thread which changes the category
LC_MESSAGES (for gettext(), gettext_l(), dgettext(), dgettext_l())
respectively the locale passed to dcgettext(), dcgettext_l()"
Bruno
[1] https://datatracker.ietf.org/doc/html/rfc8259
[2] https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtod.html
[3] https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html