Go to the first, previous, next, last section, table of contents.
At this point of the discussion we should talk about an advantage of the
GNU gettext
implementation. Some readers might have pointed out
that an internationalized program might have a poor performance if some
string has to be translated in an inner loop. While this is unavoidable
when the string varies from one run of the loop to the other it is
simply a waste of time when the string is always the same. Take the
following example:
{ while (...) { puts (gettext ("Hello world")); } }
When the locale selection does not change between two runs the resulting string is always the same. One way to use this is:
{ str = gettext ("Hello world"); while (...) { puts (str); } }
But this solution is not usable in all situation (e.g. when the locale selection changes) nor is it good readable.
The GNU C compiler, version 2.7 and above, provide another solution for this. To describe this we show here some lines of the `intl/libgettext.h' file. For an explanation of the expression command block see section `Statements and Declarations in Expressions' in The GNU CC Manual.
# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7 extern int _nl_msg_cat_cntr; # define dcgettext(domainname, msgid, category) \ (__extension__ \ ({ \ char *result; \ if (__builtin_constant_p (msgid)) \ { \ static char *__translation__; \ static int __catalog_counter__; \ if (! __translation__ \ || __catalog_counter__ != _nl_msg_cat_cntr) \ { \ __translation__ = \ dcgettext__ ((domainname), (msgid), (category)); \ __catalog_counter__ = _nl_msg_cat_cntr; \ } \ result = __translation__; \ } \ else \ result = dcgettext__ ((domainname), (msgid), (category)); \ result; \ })) # endif
The interesting thing here is the __builtin_constant_p
predicate.
This is evaluated at compile time and so optimization can take place
immediately. Here two cases are distinguished: the argument to
gettext
is not a constant value in which case simply the function
dcgettext__
is called, the real implementation of the
dcgettext
function.
If the string argument is constant we can reuse the once gained
translation when the locale selection has not changed. This is exactly
what is done here. The _nl_msg_cat_cntr
variable is defined in
the `loadmsgcat.c' which is available in `libintl.a' and is
changed whenever a new message catalog is loaded.
Go to the first, previous, next, last section, table of contents.