This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libintl.h not namespace clean in C++ mode


Hi,

Here is a bug in libintl.h, reported by Herbert Straub <herbert@linuxhacker.at>:
After #including <libintl.h> it is not possible to define member functions
called 'gettext()'.

Example:
======================= t0.cxx =========================
#include <libintl.h>
#include <string>

class foo
{
  std::string s;
public:
  foo (const char *a) : s(a) {}
  std::string gettext (void) { return s; }
};
=========================================================
$ g++-3.2.2 -O -c t0.cxx
t0.cxx:9: parse error before `,' token
t0.cxx:9: `std::string dcgettext' redeclared as different kind of symbol
/usr/include/libintl.h:52: previous declaration of `char* dcgettext(const char*, const char*, int)'
t0.cxx:9: syntax error before `{' token
t0.cxx:10: parse error before `}' token
$ g++-3.4.0 -O -c t0.cxx 
t0.cxx:9: error: expected `;' before '(' token
t0.cxx:10: error: expected `;' before '}' token

Here is a fix.


2004-06-03  Bruno Haible  <bruno@clisp.org>

	* intl/libintl.h (gettext, dgettext, ngettext, dngettext): In C++
	mode, define these as inline functions, not as macros.

--- glibc-cvs/intl/libintl.h.bak	2004-06-03 13:42:29.000000000 +0200
+++ glibc-cvs/intl/libintl.h	2004-06-03 13:37:22.000000000 +0200
@@ -1,5 +1,5 @@
 /* Message catalogs for internationalization.
-   Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 1995-1999, 2000-2002, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    This file is derived from the file libgettext.h in the GNU gettext package.
 
@@ -101,20 +101,50 @@
 /* We need LC_MESSAGES for `dgettext'.  */
 # include <locale.h>
 
-/* These must be macros.  Inlined functions are useless because the
-   `__builtin_constant_p' predicate in dcgettext would always return
-   false.  */
+# ifdef __cplusplus
 
-# define gettext(msgid) dgettext (NULL, msgid)
+/* In C++ mode, use inline functions, not macros, otherwise users cannot
+   define member functions called foo::gettext() in their own classes.  */
 
-# define dgettext(domainname, msgid) \
-  dcgettext (domainname, msgid, LC_MESSAGES)
+inline char *dgettext (__const char *__domainname, __const char *__msgid)
+     __THROW
+{
+  return dcgettext (__domainname, __msgid, LC_MESSAGES);
+}
+
+inline char *gettext (__const char *__msgid) __THROW
+{
+  return dgettext (NULL, __msgid);
+}
 
-# define ngettext(msgid1, msgid2, n) dngettext (NULL, msgid1, msgid2, n)
+inline char *dngettext (__const char *__domainname, __const char *__msgid1,
+			__const char *__msgid2, unsigned long int __n)
+     __THROW
+{
+  return dcngettext (__domainname, __msgid1, __msgid2, __n, LC_MESSAGES);
+}
+
+inline char *ngettext (__const char *__msgid1, __const char *__msgid2,
+		       unsigned long int __n) __THROW
+{
+  return dngettext (NULL, __msgid1, __msgid2, __n);
+}
+
+# else
+
+/* In C mode, prefer macros.  */
+
+#  define gettext(msgid) dgettext (NULL, msgid)
+  
+#  define dgettext(domainname, msgid) \
+  dcgettext (domainname, msgid, LC_MESSAGES)
+ 
+#  define ngettext(msgid1, msgid2, n) dngettext (NULL, msgid1, msgid2, n)
 
-# define dngettext(domainname, msgid1, msgid2, n) \
+#  define dngettext(domainname, msgid1, msgid2, n) \
   dcngettext (domainname, msgid1, msgid2, n, LC_MESSAGES)
 
+# endif /* !__cplusplus */
 #endif	/* Optimizing.  */
 
 __END_DECLS


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]