Paul Eggert wrote: > diff --git a/lib/obstack.c b/lib/obstack.c > index b5cf0d514b..9877207cb1 100644 > --- a/lib/obstack.c > +++ b/lib/obstack.c > @@ -250,8 +250,10 @@ _obstack_allocated_p (struct obstack *h, void *obj) > /* Free objects in obstack H, including OBJ and everything allocate > more recently than OBJ. If OBJ is zero, free everything in H. */ > > +#undef obstack_free > + > void
This #undef breaks library namespacing. How to reproduce: On a platform without obstack in libc, say, FreeBSD, define CPPFLAGS=-D_obstack_free=libfoo_obstack_free -Dobstack_free=libfoo_obstack_free -D_obstack_allocated_p=libfoo_obstack_allocated_p -D_obstack_begin=libfoo_obstack_begin -D_obstack_begin_1=libfoo_obstack_begin_1 -D_obstack_memory_used=libfoo_obstack_memory_used -D_obstack_newchunk=libfoo_obstack_newchunk" and compile a testdir of module 'obstack': $ ./configure $ make $ nm gllib/obstack.o Before your patch series, the result was U __stderrp U abort U exit U exit_failure U fprintf 0000000000000250 T libfoo_obstack_allocated_p 0000000000000000 T libfoo_obstack_begin 0000000000000090 T libfoo_obstack_begin_1 0000000000000280 T libfoo_obstack_free 0000000000000300 T libfoo_obstack_memory_used 0000000000000120 T libfoo_obstack_newchunk U memcpy 0000000000000000 D obstack_alloc_failed_handler 0000000000000330 t print_and_abort that is, all 'T' symbols prefixed with 'libfoo_'. Whereas now, the result is U __stderrp U abort U exit U exit_failure U fprintf 0000000000000370 T libfoo_obstack_allocated_p 0000000000000030 T libfoo_obstack_begin 0000000000000120 T libfoo_obstack_begin_1 0000000000000420 T libfoo_obstack_memory_used 0000000000000210 T libfoo_obstack_newchunk U memcpy 0000000000000000 D obstack_alloc_failed_handler 00000000000003a0 T obstack_free 0000000000000000 t print_and_abort that is, 'obstack_free' is not namespaced. Simply moving the #undef to line 323 does not work, because it produces a conflict between the macro 'obstack_free' (defined in obstack.h) and the function definition of 'obstack_free' in obstack.c. But the attached patch fixes it. It produces this symbol list: U __stderrp U abort U exit U exit_failure U fprintf 0000000000000370 T libfoo_obstack_allocated_p 0000000000000030 T libfoo_obstack_begin 0000000000000120 T libfoo_obstack_begin_1 00000000000003a0 T libfoo_obstack_free 0000000000000420 T libfoo_obstack_memory_used 0000000000000210 T libfoo_obstack_newchunk U memcpy 0000000000000000 D obstack_alloc_failed_handler 0000000000000000 t print_and_abort After this patch, what is the remaining purpose of using '__obstack_free'? Why not get back to '_obstack_free'? Your ChangeLog entry says "This is for compatibility with glibc, which in turn is for compatibility with old Gnulib." The comment in glibc says /* The default name of the function for freeing a chunk is 'obstack_free', but gnulib users can override this by defining '__obstack_free'. */ but in fact no package does this. Search https://codesearch.debian.net/search?q=define+__obstack_free&literal=1 https://codesearch.debian.net/search?q=D__obstack_free%3D&literal=1 Maybe there were packages who used this way of customizing __obstack_free twenty years ago. But they can use obstack_specify_allocation or obstack_specify_allocation_1, like everyone else: https://codesearch.debian.net/search?q=obstack_specify_allocation+%28&literal=1 2025-05-06 Bruno Haible <br...@clisp.org> obstack: Fix library namespacing (regression yesterday). * lib/obstack.in.h (__obstack_free): Define to _obstack_free, not obstack_free, within glibc and in gnulib on systems without glibc. * lib/obstack.c (obstack_free): Undefine only for the strong_alias. (obstack_free): Define as an alias of _obstack_free, not vice versa. diff --git a/lib/obstack.c b/lib/obstack.c index 9c15886717..8346c898ea 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -288,8 +288,6 @@ _obstack_allocated_p (struct obstack *h, void *obj) /* Free objects in obstack H, including OBJ and everything allocate more recently than OBJ. If OBJ is zero, free everything in H. */ -#undef obstack_free - void __obstack_free (struct obstack *h, void *obj) { @@ -322,7 +320,8 @@ __obstack_free (struct obstack *h, void *obj) /* Older versions of libc used a function _obstack_free intended to be called by non-GCC compilers. */ -strong_alias (obstack_free, _obstack_free) +#undef obstack_free +strong_alias (_obstack_free, obstack_free) _OBSTACK_INDEX_T _obstack_memory_used (struct obstack *h) diff --git a/lib/obstack.in.h b/lib/obstack.in.h index d5a0ceff6d..85252ff430 100644 --- a/lib/obstack.in.h +++ b/lib/obstack.in.h @@ -233,16 +233,23 @@ struct obstack /* control current object in current chunk */ /* Declare the external functions we use; they are in obstack.c. */ -#if defined __GL_REPLACE_OBSTACK__ -# define _obstack_newchunk rpl_obstack_newchunk -# define __obstack_free rpl_obstack_free -# define _obstack_begin rpl_obstack_begin -# define _obstack_begin_1 rpl_obstack_begin_1 -# define _obstack_memory_used rpl_obstack_memory_used -# define _obstack_allocated_p rpl_obstack_allocated_p -#elif !defined __obstack_free /* for old Gnulib */ -# define __obstack_free obstack_free +#if defined __GL_GNULIB_HEADER +/* Symbol mapping for gnulib. */ +# if defined __GL_REPLACE_OBSTACK__ +# define _obstack_newchunk rpl_obstack_newchunk +# define __obstack_free rpl_obstack_free +# define _obstack_begin rpl_obstack_begin +# define _obstack_begin_1 rpl_obstack_begin_1 +# define _obstack_memory_used rpl_obstack_memory_used +# define _obstack_allocated_p rpl_obstack_allocated_p +# else +# define __obstack_free _obstack_free +# endif +#else +/* Symbol mapping for glibc. */ +# define __obstack_free _obstack_free #endif + extern void _obstack_newchunk (struct obstack *, _OBSTACK_INDEX_T); extern int _obstack_begin (struct obstack *, _OBSTACK_INDEX_T, _OBSTACK_INDEX_T,