After compiling a testdir for modules
arpa_inet-h assert-h config-h ctype-h dirent-h errno-h error-h fcntl-h fenv-h
float-h fnmatch-h gettext-h glob-h iconv-h ieee754-h inttypes-h langinfo-h
limits-h locale-h malloc-h math-h mntent-h monetary-h netdb-h net_if-h
netinet_in-h openat-h poll-h pthread-h pty-h sched-h search-h selinux-h
signal-h spawn-h stdalign-h stdarg-h stdbit-h stdckdint-h stdcountof-h stddef-h
stdint-h stdio-h stdlib-h stdnoreturn-h string-h strings-h sysexits-h
sys_file-h sys_ioctl-h sys_msg-h sys_random-h sys_resource-h sys_select-h
sys_sem-h sys_shm-h sys_socket-h sys_stat-h sys_time-h sys_times-h sys_types-h
sys_uio-h sys_un-h sys_utsname-h sys_wait-h termcap-h terminfo-h termios-h
threads-h time-h uchar-h unistd-h unitypes-h utime-h utmp-h wchar-h wctype-h
when I compile this program foo.cc
======================================== foo.cc ===============================
#include <config.h>
#include <alloca.h>
#include <argz.h>
#include <arpa/inet.h>
#include <assert.h>
#include <byteswap.h>
#include <ctype.h>
#include <dirent.h>
#include <endian.h>
#include <errno.h>
#include <error.h>
#include <execinfo.h>
#include <fcntl.h>
#include <fenv.h>
#include <float.h>
#include <fnmatch.h>
#include <fts.h>
#include <getopt.h>
#include <glob.h>
#include <iconv.h>
#include <ieee754.h>
#include <inttypes.h>
#include <langinfo.h>
#include <limits.h>
#include <locale.h>
#include <malloc.h>
#include <math.h>
#include <mntent.h>
#include <monetary.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <obstack.h>
#include <poll.h>
#include <pthread.h>
#include <pty.h>
#include <sched.h>
#include <search.h>
#include <selinux/context.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
#include <signal.h>
#include <spawn.h>
#include <stdalign.h>
#include <stdarg.h>
#include <stdbit.h>
#include <stdbool.h>
#include <stdckdint.h>
#include <stdcountof.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdnoreturn.h>
#include <string.h>
#include <strings.h>
#include <sysexits.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/msg.h>
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <termios.h>
#include <threads.h>
#include <time.h>
#include <uchar.h>
#include <unicase.h>
#include <uniconv.h>
#include <unictype.h>
#include <unigbrk.h>
#include <unilbrk.h>
#include <uniname.h>
#include <uninorm.h>
#include <unistd.h>
#include <unistdio.h>
#include <unistr.h>
#include <unitypes.h>
#include <uniwbrk.h>
#include <uniwidth.h>
#include <utime.h>
#include <utmp.h>
#include <wchar.h>
#include <wctype.h>
int main ()
{
}
=========================================================================
$ cd build
$ g++ -Wall -Igllib -I../gllib -I. -DGNULIB_POSIXCHECK foo.cc
I get 4 compilation errors:
In file included from /usr/include/string.h:462,
from gllib/string.h:41,
from /usr/include/argz.h:24,
from foo.cc:6:
gllib/string.h:960:1: error: type of ‘memchr’ is unknown
960 | _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - "
| ^~~~~~~~~~~~~~~
gllib/string.h:960:1: error: ‘int memchr’ redeclared as different kind of entity
960 | _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - "
| ^~~~~~~~~~~~~~~
/usr/include/string.h:89:20: note: previous declaration ‘const void*
memchr(const void*, int, size_t)’
89 | extern const void *memchr (const void *__s, int __c, size_t __n)
| ^~~~~~
gllib/string.h:1641:1: error: type of ‘strstr’ is unknown
1641 | _GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and
cannot "
| ^~~~~~~~~~~~~~~
gllib/string.h:1641:1: error: ‘int strstr’ redeclared as different kind of
entity
1641 | _GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and
cannot "
| ^~~~~~~~~~~~~~~
/usr/include/string.h:332:20: note: previous declaration ‘const char*
strstr(const char*, const char*)’
332 | extern const char *strstr (const char *__haystack, const char *__needle)
| ^~~~~~
gllib/math.h:1738:1: error: type of ‘frexp’ is unknown
1738 | _GL_WARN_ON_USE (frexp, "frexp is unportable - "
| ^~~~~~~~~~~~~~~
gllib/math.h:1738:1: error: ‘int frexp’ redeclared as different kind of entity
1738 | _GL_WARN_ON_USE (frexp, "frexp is unportable - "
| ^~~~~~~~~~~~~~~
In file included from /usr/include/features.h:502,
from /usr/include/argz.h:22:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:98:1: note: previous declaration
‘double frexp(double, int*)’
98 | __MATHCALL (frexp,, (_Mdouble_ __x, int *__exponent));
| ^~~~~~~~~~
gllib/math.h:2017:1: error: type of ‘ldexp’ is unknown
2017 | _GL_WARN_ON_USE (ldexp, "ldexp is unportable - "
| ^~~~~~~~~~~~~~~
gllib/math.h:2017:1: error: ‘int ldexp’ redeclared as different kind of entity
2017 | _GL_WARN_ON_USE (ldexp, "ldexp is unportable - "
| ^~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:101:1: note: previous
declaration ‘double ldexp(double, int)’
101 | __MATHCALL (ldexp,, (_Mdouble_ __x, int __exponent));
| ^~~~~~~~~~
The cause is that these function are defined as overloaded in C++.
For instance frexp, ldexp:
https://en.cppreference.com/w/cpp/numeric/math/frexp
https://en.cppreference.com/w/cpp/numeric/math/ldexp
This patch fixes the compilation error.
2025-11-23 Bruno Haible <[email protected]>
math-h, string-h: Fix C++ compilation errors with GNULIB_POSIXCHECK.
* lib/math.in.h (frexp, ldexp): Use _GL_WARN_ON_USE_CXX instead of
_GL_WARN_ON_USE.
* lib/string.in.h (memchr, strstr): Likewise.
diff --git a/lib/math.in.h b/lib/math.in.h
index fae66de5f4..71f4cdfa69 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -1188,8 +1188,10 @@ _GL_CXXALIASWARN1 (frexp, double, (double x, int
*expptr));
#elif defined GNULIB_POSIXCHECK
# undef frexp
/* Assume frexp is always declared. */
-_GL_WARN_ON_USE (frexp, "frexp is unportable - "
- "use gnulib module frexp for portability");
+_GL_WARN_ON_USE_CXX (frexp,
+ double, double, (double, int *),
+ "frexp is unportable - "
+ "use gnulib module frexp for portability");
#endif
/* Write x as
@@ -1467,8 +1469,10 @@ _GL_CXXALIASWARN1 (ldexp, double, (double x, int exp));
#elif defined GNULIB_POSIXCHECK
# undef ldexp
/* Assume ldexp is always declared. */
-_GL_WARN_ON_USE (ldexp, "ldexp is unportable - "
- "use gnulib module ldexp for portability");
+_GL_WARN_ON_USE_CXX (ldexp,
+ double, double, (double, int),
+ "ldexp is unportable - "
+ "use gnulib module ldexp for portability");
#endif
/* Return x * 2^exp. */
diff --git a/lib/string.in.h b/lib/string.in.h
index 8b56acfb51..2dddbf715f 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -410,8 +410,10 @@ _GL_CXXALIASWARN (memchr);
# endif
#elif defined GNULIB_POSIXCHECK
/* Assume memchr is always declared. */
-_GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - "
- "use gnulib module memchr for portability" );
+_GL_WARN_ON_USE_CXX (memchr,
+ const void *, void *, (void const *, int, size_t),
+ "memchr has platform-specific bugs - "
+ "use gnulib module memchr for portability" );
#endif
/* Are S1 and S2, of size N, bytewise equal? */
@@ -1091,11 +1093,13 @@ _GL_CXXALIASWARN (strstr);
as a sequence of bytes, not of characters. */
# undef strstr
/* Assume strstr is always declared. */
-_GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot "
- "work correctly on character strings in most "
- "multibyte locales - "
- "use mbsstr if you care about internationalization, "
- "or use strstr if you care about speed");
+_GL_WARN_ON_USE_CXX (strstr,
+ const char *, char *, (const char *, const char *),
+ "strstr is quadratic on many systems, and cannot "
+ "work correctly on character strings in most "
+ "multibyte locales - "
+ "use mbsstr if you care about internationalization, "
+ "or use strstr if you care about speed");
#endif
/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive