We're not yet done with strnul. It broke the libunistring build: /usr/bin/ld: .libs/libunistring_la-string.o: in function `libunistring_memeq': /builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:970: multiple definition of `libunistring_memeq'; .libs/libunistring_la-string.o:/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:970: first defined here /usr/bin/ld: .libs/libunistring_la-string.o: in function `libunistring_streq': /builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1355: multiple definition of `libunistring_streq'; .libs/libunistring_la-string.o:/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1355: first defined here /usr/bin/ld: .libs/libunistring_la-string.o: in function `libunistring_gl_strnul': /builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1797: multiple definition of `libunistring_gl_strnul'; .libs/libunistring_la-string.o:/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1797: first defined here collect2: error: ld returned 1 exit status make[3]: *** [Makefile:5886: libunistring.la] Error 1 make[3]: Leaving directory '/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib'
The cause of this error is that the Makefile passing the object file libunistring_la-string.lo twice in the link command line. And this is because it is listed in two different modules: modules/strnul:lib_SOURCES += string.c modules/stringeq:lib_SOURCES += string.c A possible way to avoid listing the same .lo file twice in the link is to use AC_LIBOBJ. But AC_LIBOBJ has problems too; the better way is to use different object files for different functions. There's no reason why gl_strnul() should be defined in the same object file as streq() and memeq(). 2026-02-28 Bruno Haible <[email protected]> strnul: Fix link-time error. * lib/string.in.h (_GL_STRNUL_INLINE): New macro. (gl_strnul): Use it instead of _GL_STRING_INLINE. * lib/strnul.c: New file. * lib/string.c: Update comment. * modules/strnul (Files): Add strnul.c. Remove string.c. (Makefile.am): Update accordingly. diff --git a/lib/string.c b/lib/string.c index b8f079aa78..610da9f12e 100644 --- a/lib/string.c +++ b/lib/string.c @@ -1,4 +1,4 @@ -/* streq, memeq, gl_strnul functions. +/* streq, memeq functions. Copyright (C) 2025-2026 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify diff --git a/lib/string.in.h b/lib/string.in.h index a98552b8f5..c930ecc4e0 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -81,10 +81,12 @@ #endif _GL_INLINE_HEADER_BEGIN - #ifndef _GL_STRING_INLINE # define _GL_STRING_INLINE _GL_INLINE #endif +#ifndef _GL_STRNUL_INLINE +# define _GL_STRNUL_INLINE _GL_INLINE +#endif /* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers that can be freed by passing them as the Ith argument to the @@ -1243,10 +1245,10 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " # ifdef __cplusplus extern "C" { # endif -_GL_STRING_INLINE const char *gl_strnul (const char *string) +_GL_STRNUL_INLINE const char *gl_strnul (const char *string) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1)); -_GL_STRING_INLINE const char *gl_strnul (const char *string) +_GL_STRNUL_INLINE const char *gl_strnul (const char *string) { /* In gcc >= 7 or clang >= 4, we could use the expression strchr (string, '\0') diff --git a/lib/strnul.c b/lib/strnul.c new file mode 100644 index 0000000000..a567f0722e --- /dev/null +++ b/lib/strnul.c @@ -0,0 +1,19 @@ +/* gl_strnul function. + Copyright (C) 2025-2026 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +#define _GL_STRNUL_INLINE _GL_EXTERN_INLINE +#include <config.h> +#include <string.h> diff --git a/modules/strnul b/modules/strnul index 52d6729c8c..7accd5fb0f 100644 --- a/modules/strnul +++ b/modules/strnul @@ -2,7 +2,7 @@ Description: strnul() function: return pointer to terminating NUL byte. Files: -lib/string.c +lib/strnul.c Depends-on: string-h @@ -11,7 +11,7 @@ configure.ac: gl_STRING_MODULE_INDICATOR([strnul]) Makefile.am: -lib_SOURCES += string.c +lib_SOURCES += strnul.c Include: <string.h>
