Paul Eggert wrote: > I noticed that the other changes in that patch never invoke > xcharalloc (n); they always invoked XNMALLOC (n, char) instead. > If that's the preferred usage, perhaps we should remove xcharalloc? > On the other hand I prefer not using macros (which is why I added > xcharalloc in the first place).
That's up to you. I use XNMALLOC (n, char) because once I'm used to XNMALLOC (n, T) for various other types T, it's easy to understand what XNMALLOC (n, char) means. > > ! #define XMALLOC(T) \ > > ! ((T *) xmalloc (sizeof (T))) > > A minor point: I prefer using lower-case names for macro arguments and > avoiding backslash-newline when defining short macros. As you like. I used an uppercase T because in the C++ community, the first type template argument is always called 'T'. > HAVE_INLINE isn't defined by xalloc.m4 or any of xalloc's prerequisites. The purpose of HAVE_INLINE is to avoid bloating the binary when compiling with a compiler that doesn't support 'inline'. With such a compiler, AC_C_INLINE defines 'inline' to empty, and such older compilers don't optimize away unused static functions. So if you compile 30 .c files that each #include "xalloc.h", you end up with 30 copies of xnmalloc, xnrealloc etc. in the library or executable. Apart from being bloat, it also hampers debugging, because when you set a breakpoint in such a function, gdb will set a breakpoint in one of the copies, chosen randomly, not in all 30 copies. What I suggest to get around this, is to define these functions with external linkage when such a compiler is in use. To avoid code duplication, one needs to move the function definitions to a separate file. Is this acceptable? 2006-11-06 Bruno Haible <[EMAIL PROTECTED]> * lib/xalloc.h (xnmalloc, xnrealloc, x2nrealloc, xcharalloc): Move definition to xalloc-inline.h. Keep only their declarations, if !HAVE_INLINE. * lib/xalloc-inline.h: New file, extracted from xalloc.h. * lib/xmalloc.c [!HAVE_INLINE]: Include xalloc-inline.h. * m4/xalloc.m4 (gl_PREREQ_XALLOC): Require gl_INLINE instead of AC_C_INLINE. * modules/xalloc (Files): Add lib/xalloc-inline.h, m4/inline.m4. *** gnulib-20061106/lib/xalloc.h 2006-11-07 01:19:06.000000000 +0100 --- gnulib-20061106-modified/lib/xalloc.h 2006-11-07 02:39:50.000000000 +0100 *************** *** 70,94 **** /* Allocate an array of N objects, each with S bytes of memory, dynamically, with error checking. S must be nonzero. */ ! ! static inline void * ! xnmalloc (size_t n, size_t s) ! { ! if (xalloc_oversized (n, s)) ! xalloc_die (); ! return xmalloc (n * s); ! } /* Change the size of an allocated block of memory P to an array of N objects each of S bytes, with error checking. S must be nonzero. */ ! ! static inline void * ! xnrealloc (void *p, size_t n, size_t s) ! { ! if (xalloc_oversized (n, s)) ! xalloc_die (); ! return xrealloc (p, n * s); ! } /* If P is null, allocate a block of at least *PN such objects; otherwise, reallocate P so that it contains more than *PN objects --- 70,84 ---- /* Allocate an array of N objects, each with S bytes of memory, dynamically, with error checking. S must be nonzero. */ ! #if !HAVE_INLINE ! extern void * xnmalloc (size_t n, size_t s); ! #endif /* Change the size of an allocated block of memory P to an array of N objects each of S bytes, with error checking. S must be nonzero. */ ! #if !HAVE_INLINE ! extern void * xnrealloc (void *p, size_t n, size_t s); ! #endif /* If P is null, allocate a block of at least *PN such objects; otherwise, reallocate P so that it contains more than *PN objects *************** *** 144,179 **** } */ ! ! static inline void * ! x2nrealloc (void *p, size_t *pn, size_t s) ! { ! size_t n = *pn; ! ! if (! p) ! { ! if (! n) ! { ! /* The approximate size to use for initial small allocation ! requests, when the invoking code specifies an old size of ! zero. 64 bytes is the largest "small" request for the ! GNU C library malloc. */ ! enum { DEFAULT_MXFAST = 64 }; ! ! n = DEFAULT_MXFAST / s; ! n += !n; ! } ! } ! else ! { ! if (((size_t) -1) / 2 / s < n) ! xalloc_die (); ! n *= 2; ! } ! ! *pn = n; ! return xrealloc (p, n * s); ! } /* In the following macros, T must be an elementary or structure/union or typedef'ed type, or a pointer to such a type. To apply one of the --- 134,142 ---- } */ ! #if !HAVE_INLINE ! extern void * x2nrealloc (void *p, size_t *pn, size_t s); ! #endif /* In the following macros, T must be an elementary or structure/union or typedef'ed type, or a pointer to such a type. To apply one of the *************** *** 200,210 **** /* Return a pointer to a new buffer of N bytes. This is like xmalloc, except it returns char *. */ ! static inline char * ! xcharalloc (size_t n) ! { ! return XNMALLOC (n, char); ! } # ifdef __cplusplus } --- 163,177 ---- /* Return a pointer to a new buffer of N bytes. This is like xmalloc, except it returns char *. */ ! #if !HAVE_INLINE ! extern inline char * xcharalloc (size_t n); ! #endif ! ! #if HAVE_INLINE ! # define STATIC_INLINE static inline ! # include "xalloc-inline.h" ! # undef STATIC_INLINE ! #endif # ifdef __cplusplus } *** /dev/null 2003-09-23 19:59:22.000000000 +0200 --- gnulib-20061106-modified/lib/xalloc-inline.h 2006-11-07 02:40:07.000000000 +0100 *************** *** 0 **** --- 1,70 ---- + /* xalloc-inline.h -- inline functions for malloc with out-of-memory checking + + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + + STATIC_INLINE void * + xnmalloc (size_t n, size_t s) + { + if (xalloc_oversized (n, s)) + xalloc_die (); + return xmalloc (n * s); + } + + STATIC_INLINE void * + xnrealloc (void *p, size_t n, size_t s) + { + if (xalloc_oversized (n, s)) + xalloc_die (); + return xrealloc (p, n * s); + } + + STATIC_INLINE void * + x2nrealloc (void *p, size_t *pn, size_t s) + { + size_t n = *pn; + + if (! p) + { + if (! n) + { + /* The approximate size to use for initial small allocation + requests, when the invoking code specifies an old size of + zero. 64 bytes is the largest "small" request for the + GNU C library malloc. */ + enum { DEFAULT_MXFAST = 64 }; + + n = DEFAULT_MXFAST / s; + n += !n; + } + } + else + { + if (((size_t) -1) / 2 / s < n) + xalloc_die (); + n *= 2; + } + + *pn = n; + return xrealloc (p, n * s); + } + + STATIC_INLINE char * + xcharalloc (size_t n) + { + return XNMALLOC (n, char); + } *** gnulib-20061106/lib/xmalloc.c 2006-11-07 01:19:06.000000000 +0100 --- gnulib-20061106-modified/lib/xmalloc.c 2006-11-07 02:39:44.000000000 +0100 *************** *** 117,119 **** --- 117,127 ---- { return xmemdup (string, strlen (string) + 1); } + + /* Implement the functions that could not be declared inline in the header + file because the compiler does not support 'inline'. */ + #if !HAVE_INLINE + # define STATIC_INLINE + # include "xalloc-inline.h" + # undef STATIC_INLINE + #endif *** gnulib-20061106/m4/xalloc.m4 2006-11-07 01:19:06.000000000 +0100 --- gnulib-20061106-modified/m4/xalloc.m4 2006-11-07 02:41:46.000000000 +0100 *************** *** 1,4 **** ! # xalloc.m4 serial 15 dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, --- 1,4 ---- ! # xalloc.m4 serial 16 dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, *************** *** 14,20 **** # Prerequisites of lib/xalloc.h. AC_DEFUN([gl_PREREQ_XALLOC], [ ! AC_REQUIRE([AC_C_INLINE]) : ]) --- 14,20 ---- # Prerequisites of lib/xalloc.h. AC_DEFUN([gl_PREREQ_XALLOC], [ ! AC_REQUIRE([gl_INLINE]) : ]) *** gnulib-20061106/modules/xalloc 2006-10-13 01:34:46.000000000 +0200 --- gnulib-20061106-modified/modules/xalloc 2006-11-07 02:41:09.000000000 +0100 *************** *** 3,10 **** --- 3,12 ---- Files: lib/xalloc.h + lib/xalloc-inline.h lib/xmalloc.c m4/xalloc.m4 + m4/inline.m4 Depends-on: xalloc-die