[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gnulib] xmalloc, xnmalloc
From: |
Bruno Haible |
Subject: |
Re: [bug-gnulib] xmalloc, xnmalloc |
Date: |
Tue, 7 Nov 2006 14:45:14 +0100 |
User-agent: |
KMail/1.9.1 |
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 <address@hidden>
* 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
- Re: [bug-gnulib] xmalloc, xnmalloc (was: Re: C++ support (2)), Bruno Haible, 2006/11/01
- Re: [bug-gnulib] xmalloc, xnmalloc, Paul Eggert, 2006/11/01
- Re: [bug-gnulib] xmalloc, xnmalloc, Bruno Haible, 2006/11/02
- Re: [bug-gnulib] xmalloc, xnmalloc, Paul Eggert, 2006/11/02
- Re: [bug-gnulib] xmalloc, xnmalloc, Bruno Haible, 2006/11/06
- Re: [bug-gnulib] xmalloc, xnmalloc, Paul Eggert, 2006/11/06
- Re: [bug-gnulib] xmalloc, xnmalloc, Bruno Haible, 2006/11/07
- Re: [bug-gnulib] xmalloc, xnmalloc,
Bruno Haible <=
- Re: [bug-gnulib] xmalloc, xnmalloc, Paul Eggert, 2006/11/07
- Re: [bug-gnulib] xmalloc, xnmalloc, Bruno Haible, 2006/11/08
- Re: [bug-gnulib] xmalloc, xnmalloc, Bruno Haible, 2006/11/08
- Re: [bug-gnulib] xmalloc, xnmalloc, Bruno Haible, 2006/11/07