[PATCH 0/5] obstacks again
Paul Eggert
eggert@cs.ucla.edu
Tue Nov 4 08:43:00 GMT 2014
On 11/02/2014 11:07 PM, Alan Modra wrote:
> Really, it's a fiction that the size argument of obstack_blank_fast has a type.
Yes and no. It's a fiction in the sense that obstack_blank_fast is a macro, so
its argument doesn't actually have a C type. But it's not a fiction in the
sense that obstack_blank_fast can be documented as if it were a function, and if
a program calls it with valid arguments that a function would have, it behaves
like that function.
In this sense, obstack_blank_fast is like putchar. Although putchar is a macro
and strictly speaking its argument doesn't have a C type, it is documented to
take a value of type int, and if you call it according to its specification it
behaves properly.
> I've added: "Earlier versions of obstacks allowed you to use
> @code{obstack_blank} to shrink objects. This will no longer work."
But this doesn't suffice for obstack_blank_stack, which *can* shrink objects and
where user code relies on this feature. E.g., the following code (taken from
GCC's finish_regexp_representation) should work if the current object size fits
into 'int', and should continue to work if we change its 'int' to 'size_t' and
allocate objects larger than what 'int' can represent:
int length = obstack_object_size (&irp);
obstack_blank_fast (&irp, -length);
> There another gnulib issue too. AC_FUNC_OBSTACK is no longer correct. The
> system libc may support obstacks, but not the current version. It seems to me
> the easiest solution is to always include obstack.o in libgnu.a.
Thanks, I wrote a "harder" solution, which builds obstack.o only if the system
version doesn't work with arbitrary size_t values. This is always true now but
won't be once these fixes make their way into glibc.
> Ianother small tweak: Don't use alignof.h if __IBM__ALIGNOF__ is defined
> (alignof.h just uses __alignof__ in that case), or when __alignof__ is defined
> (for oddball systems, or testing).
I'd rather insulate obstack from that internal detail of alignof. I gave a shot
at doing this in a different way, which preserves the insulation better.
A couple more things. obstack_chunkfun and obstack_freefun should also return
void. And the code should avoid casting function values from one calling
convention to another: this sort-of-works with the old API on glibc's current
platforms but is likely to cause problems with the transition to the new one.
I installed the attached patches to gnulib to try to implement the above; please
let me know of any issues.
-------------- next part --------------
From 3d99d9fb66ceea0f93a6cfeb496f0471efa212d3 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 3 Nov 2014 16:34:52 -0800
Subject: [PATCH 1/4] obstack: port to platforms that #define __alignof__
* lib/obstack.c: Include <alignof.h> if !defined __alignof__,
not if !_LIBC. We don't know of any platforms that #define
__alignof__, but it might be useful in tests. Conversely,
glibc assumes GCC.
---
ChangeLog | 8 ++++++++
lib/obstack.c | 5 ++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 6728893..274b794 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-11-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ obstack: port to platforms that #define __alignof__
+ * lib/obstack.c: Include <alignof.h> if !defined __alignof__,
+ not if !_LIBC. We don't know of any platforms that #define
+ __alignof__, but it might be useful in tests. Conversely,
+ glibc assumes GCC.
+
2014-11-03 Pádraig Brady <P@draigBrady.com>
linkat: don't unconditionally replace on GNU/Linux
diff --git a/lib/obstack.c b/lib/obstack.c
index ba7dff3..d763c57 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -48,7 +48,10 @@
#endif
#ifndef _OBSTACK_ELIDE_CODE
-# if !defined _LIBC && !defined __GNUC__
+/* If GCC, or if an oddball (testing?) host that #defines __alignof__,
+ use the already-supplied __alignof__. Otherwise, this must be Gnulib
+ (as glibc assumes GCC); defer to Gnulib's alignof_type. */
+# if !defined __GNUC__ && !defined __alignof__
# include <alignof.h>
# define __alignof__(type) alignof_type (type)
# endif
--
1.9.3
-------------- next part --------------
From 035a186cc20f21354720c51cc303b6c0d6017c5f Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 3 Nov 2014 16:36:27 -0800
Subject: [PATCH 2/4] obstack: do not assume system-supplied obstack is size_t
safe
* m4/obstack.m4: New file.
* modules/obstack (Files): Add it.
---
ChangeLog | 4 ++++
m4/obstack.m4 | 35 +++++++++++++++++++++++++++++++++++
modules/obstack | 1 +
3 files changed, 40 insertions(+)
create mode 100644 m4/obstack.m4
diff --git a/ChangeLog b/ChangeLog
index 274b794..23accbe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2014-11-03 Paul Eggert <eggert@cs.ucla.edu>
+ obstack: do not assume system-supplied obstack is size_t safe
+ * m4/obstack.m4: New file.
+ * modules/obstack (Files): Add it.
+
obstack: port to platforms that #define __alignof__
* lib/obstack.c: Include <alignof.h> if !defined __alignof__,
not if !_LIBC. We don't know of any platforms that #define
diff --git a/m4/obstack.m4 b/m4/obstack.m4
new file mode 100644
index 0000000..bc5b4a4
--- /dev/null
+++ b/m4/obstack.m4
@@ -0,0 +1,35 @@
+# See if we need to provide obstacks.
+
+dnl Copyright 1996-2014 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This replaces Autoconf's AC_FUNC_OBSTACK.
+dnl The Autoconf version should be marked obsolete at some point.
+
+AC_DEFUN([AC_FUNC_OBSTACK],
+ [AC_LIBSOURCES([obstack.h, obstack.c])dnl
+ AC_CACHE_CHECK([for obstacks that work with any size object],
+ [ac_cv_func_obstack],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include "obstack.h"
+ void *obstack_chunk_alloc (size_t n) { return 0; }
+ void obstack_chunk_free (void *p) { }
+ /* Check that an internal function returns size_t, not int. */
+ size_t _obstack_memory_used (struct obstack *);
+ ]],
+ [[struct obstack mem;
+ obstack_init (&mem);
+ obstack_free (&mem, 0);
+ ]])],
+ [ac_cv_func_obstack=yes],
+ [ac_cv_func_obstack=no])])
+ if test "$ac_cv_func_obstack" = yes; then
+ AC_DEFINE([HAVE_OBSTACK], 1,
+ [Define to 1 if the system has obstacks that work with any size object.])
+ else
+ AC_LIBOBJ([obstack])
+ fi
+])
diff --git a/modules/obstack b/modules/obstack
index 36dc444..e0b528e 100644
--- a/modules/obstack
+++ b/modules/obstack
@@ -4,6 +4,7 @@ Memory allocation, optimized for stack-like allocation patterns.
Files:
lib/obstack.h
lib/obstack.c
+m4/obstack.m4
Depends-on:
alignof
--
1.9.3
-------------- next part --------------
From 488669cb5f25d4e9546fb8727f0ec117a6b828f2 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Mon, 3 Nov 2014 17:32:27 -0800
Subject: [PATCH 3/4] obstack: fix macro return values
* lib/obstack.h (obstack_next_free): Return void *.
(obstack_1grow_fast, obstack_blank_fast): Return void.
For __GNUC__ macros:
(obstack_1grow, obstack_blank): Remove now unnecessary (void) 0.
For !__GNUC__ macros:
(obstack_make_room, obstack_grow, obstack_grow0)
(obstack_ptr_grow_fast, obstack_int_grow_fast): Return void.
---
ChangeLog | 11 +++++++++++
lib/obstack.h | 27 +++++++++++++++------------
2 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 23accbe..ac78e88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-11-03 Alan Modra <amodra@gmail.com>
+
+ obstack: fix macro return values
+ * lib/obstack.h (obstack_next_free): Return void *.
+ (obstack_1grow_fast, obstack_blank_fast): Return void.
+ For __GNUC__ macros:
+ (obstack_1grow, obstack_blank): Remove now unnecessary (void) 0.
+ For !__GNUC__ macros:
+ (obstack_make_room, obstack_grow, obstack_grow0)
+ (obstack_ptr_grow_fast, obstack_int_grow_fast): Return void.
+
2014-11-03 Paul Eggert <eggert@cs.ucla.edu>
obstack: do not assume system-supplied obstack is size_t safe
diff --git a/lib/obstack.h b/lib/obstack.h
index ba4de1d..61b824b 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -219,7 +219,7 @@ extern int obstack_exit_failure;
/* Pointer to next byte not yet allocated in current chunk. */
-#define obstack_next_free(h) ((h)->next_free)
+#define obstack_next_free(h) ((void *) (h)->next_free)
/* Mask specifying low bits that should be clear in address of an object. */
@@ -252,9 +252,9 @@ extern int obstack_exit_failure;
#define obstack_freefun(h, newfreefun) \
((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))
-#define obstack_1grow_fast(h, achar) (*((h)->next_free)++ = (achar))
+#define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
-#define obstack_blank_fast(h, n) ((h)->next_free += (n))
+#define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
#define obstack_memory_used(h) _obstack_memory_used (h)
@@ -322,8 +322,7 @@ extern int obstack_exit_failure;
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < 1) \
_obstack_newchunk (__o, 1); \
- obstack_1grow_fast (__o, datum); \
- (void) 0; })
+ obstack_1grow_fast (__o, datum); })
/* These assume that the obstack alignment is good enough for pointers
or ints, and that the data added so far to the current object
@@ -365,8 +364,7 @@ extern int obstack_exit_failure;
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
- obstack_blank_fast (__o, __len); \
- (void) 0; })
+ obstack_blank_fast (__o, __len); })
# define obstack_alloc(OBSTACK, length) \
__extension__ \
@@ -435,14 +433,16 @@ extern int obstack_exit_failure;
# define obstack_make_room(h, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
- ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0))
+ ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0), \
+ (void) 0)
# define obstack_grow(h, where, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
- (h)->next_free += (h)->temp.i)
+ (h)->next_free += (h)->temp.i, \
+ (void) 0)
# define obstack_grow0(h, where, length) \
((h)->temp.i = (length), \
@@ -450,7 +450,8 @@ extern int obstack_exit_failure;
? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
(h)->next_free += (h)->temp.i, \
- *((h)->next_free)++ = 0)
+ *((h)->next_free)++ = 0, \
+ (void) 0)
# define obstack_1grow(h, datum) \
(((obstack_room (h) < 1) \
@@ -468,10 +469,12 @@ extern int obstack_exit_failure;
obstack_int_grow_fast (h, datum))
# define obstack_ptr_grow_fast(h, aptr) \
- (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
+ (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr), \
+ (void) 0)
# define obstack_int_grow_fast(h, aint) \
- (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
+ (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint), \
+ (void) 0)
# define obstack_blank(h, length) \
((h)->temp.i = (length), \
--
1.9.3
-------------- next part --------------
From ecfbf8c8668da0021015796361272e402efe01e4 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 4 Nov 2014 00:31:31 -0800
Subject: [PATCH 4/4] obstack: avoid potentially-nonportable function casts
* lib/obstack.c (CALL_CHUNKFUN, CALL_FREEFUN):
Remove, replacing with ...
(call_chunkfun, call_freefun): New static functions.
All uses changed. Avoid potentially-nonportable casts.
(chunkfun_type, freefun_type): Remove typedefs; no longer used.
(_obstack_begin_worker): Omit last two args, since they
rely on potentially-nonportable casts. All callers changed.
* lib/obstack.h (_OBSTACK_CAST): New macro.
Use it everywhere the old API used a potentially-nonportable cast.
The new API doesn't cast.
(struct obstack): Use unions rather than requiring
potentially-nonportable casts.
(obstack_chunkfun, obstack_freefun): Return void.
---
ChangeLog | 17 +++++++++++++++
lib/obstack.c | 69 +++++++++++++++++++++++++++--------------------------------
lib/obstack.h | 48 +++++++++++++++++++++++++----------------
3 files changed, 79 insertions(+), 55 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ac78e88..3b3af67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-11-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ obstack: avoid potentially-nonportable function casts
+ * lib/obstack.c (CALL_CHUNKFUN, CALL_FREEFUN):
+ Remove, replacing with ...
+ (call_chunkfun, call_freefun): New static functions.
+ All uses changed. Avoid potentially-nonportable casts.
+ (chunkfun_type, freefun_type): Remove typedefs; no longer used.
+ (_obstack_begin_worker): Omit last two args, since they
+ rely on potentially-nonportable casts. All callers changed.
+ * lib/obstack.h (_OBSTACK_CAST): New macro.
+ Use it everywhere the old API used a potentially-nonportable cast.
+ The new API doesn't cast.
+ (struct obstack): Use unions rather than requiring
+ potentially-nonportable casts.
+ (obstack_chunkfun, obstack_freefun): Return void.
+
2014-11-03 Alan Modra <amodra@gmail.com>
obstack: fix macro return values
diff --git a/lib/obstack.c b/lib/obstack.c
index d763c57..90555ed 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -76,41 +76,38 @@
MAX (sizeof (uintmax_t), \
sizeof (void *)))
-/* Define a macro that either calls functions with the traditional malloc/free
- calling interface, or calls functions with the mmalloc/mfree interface
- (that adds an extra first argument), based on the state of use_extra_arg.
- For free, do not use ?:, since some compilers, like the MIPS compilers,
- do not allow (expr) ? void : void. */
-
-# define CALL_CHUNKFUN(h, size) \
- (((h)->use_extra_arg) \
- ? (*(h)->chunkfun)((h)->extra_arg, (size)) \
- : (*(struct _obstack_chunk *(*)(size_t))(h)->chunkfun)((size)))
-
-# define CALL_FREEFUN(h, old_chunk) \
- do { \
- if ((h)->use_extra_arg) \
- (*(h)->freefun)((h)->extra_arg, (old_chunk)); \
- else \
- (*(void (*)(void *))(h)->freefun)((old_chunk)); \
- } while (0)
+/* Call functions with either the traditional malloc/free calling
+ interface, or the mmalloc/mfree interface (that adds an extra first
+ argument), based on the value of use_extra_arg. */
+
+static void *
+call_chunkfun (struct obstack *h, size_t size)
+{
+ if (h->use_extra_arg)
+ return h->chunkfun.extra (h->extra_arg, size);
+ else
+ return h->chunkfun.plain (size);
+}
+
+static void
+call_freefun (struct obstack *h, void *old_chunk)
+{
+ if (h->use_extra_arg)
+ h->freefun.extra (h->extra_arg, old_chunk);
+ else
+ h->freefun.plain (old_chunk);
+}
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
- CHUNKFUN is the function to use to allocate chunks,
- and FREEFUN the function to free them.
Return nonzero if successful, calls obstack_alloc_failed_handler if
allocation fails. */
-typedef struct _obstack_chunk * (*chunkfun_type) (void *, size_t);
-typedef void (*freefun_type) (void *, struct _obstack_chunk *);
-
static int
_obstack_begin_worker (struct obstack *h,
- _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
- chunkfun_type chunkfun, freefun_type freefun)
+ _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)
{
struct _obstack_chunk *chunk; /* points to new chunk */
@@ -133,12 +130,10 @@ _obstack_begin_worker (struct obstack *h,
size = 4096 - extra;
}
- h->chunkfun = chunkfun;
- h->freefun = freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
- chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
+ chunk = h->chunk = call_chunkfun (h, h->chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
@@ -157,10 +152,10 @@ _obstack_begin (struct obstack *h,
void *(*chunkfun) (size_t),
void (*freefun) (void *))
{
+ h->chunkfun.plain = chunkfun;
+ h->freefun.plain = freefun;
h->use_extra_arg = 0;
- return _obstack_begin_worker (h, size, alignment,
- (chunkfun_type) chunkfun,
- (freefun_type) freefun);
+ return _obstack_begin_worker (h, size, alignment);
}
int
@@ -170,11 +165,11 @@ _obstack_begin_1 (struct obstack *h,
void (*freefun) (void *, void *),
void *arg)
{
+ h->chunkfun.extra = chunkfun;
+ h->freefun.extra = freefun;
h->extra_arg = arg;
h->use_extra_arg = 1;
- return _obstack_begin_worker (h, size, alignment,
- (chunkfun_type) chunkfun,
- (freefun_type) freefun);
+ return _obstack_begin_worker (h, size, alignment);
}
/* Allocate a new current chunk for the obstack *H
@@ -202,7 +197,7 @@ _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
/* Allocate and initialize the new chunk. */
if (obj_size <= sum1 && sum1 <= sum2)
- new_chunk = CALL_CHUNKFUN (h, new_size);
+ new_chunk = call_chunkfun (h, new_size);
if (!new_chunk)
(*obstack_alloc_failed_handler)();
h->chunk = new_chunk;
@@ -225,7 +220,7 @@ _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
h->alignment_mask)))
{
new_chunk->prev = old_chunk->prev;
- CALL_FREEFUN (h, old_chunk);
+ call_freefun (h, old_chunk);
}
h->object_base = object_base;
@@ -276,7 +271,7 @@ _obstack_free (struct obstack *h, void *obj)
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
- CALL_FREEFUN (h, lp);
+ call_freefun (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
diff --git a/lib/obstack.h b/lib/obstack.h
index 61b824b..7b6dee8 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -116,10 +116,12 @@
and "long" for these two types. */
# define _OBSTACK_SIZE_T unsigned int
# define _CHUNK_SIZE_T unsigned long
+# define _OBSTACK_CAST(type, expr) ((type) (expr))
#else
/* Version 2 with sane types, especially for 64-bit hosts. */
# define _OBSTACK_SIZE_T size_t
# define _CHUNK_SIZE_T size_t
+# define _OBSTACK_CAST(type, expr) (expr)
#endif
/* If B is the base of an object addressed by P, return the result of
@@ -167,11 +169,19 @@ struct obstack /* control current object in current chunk */
void *p;
} temp; /* Temporary for some macros. */
_OBSTACK_SIZE_T alignment_mask; /* Mask of alignment for each object. */
- /* These prototypes vary based on 'use_extra_arg', and we use
- casts to the prototypeless function type in all assignments,
- but having prototypes here quiets -Wstrict-prototypes. */
- struct _obstack_chunk *(*chunkfun) (void *, size_t);
- void (*freefun) (void *, struct _obstack_chunk *);
+
+ /* These prototypes vary based on 'use_extra_arg'. */
+ union
+ {
+ void *(*plain) (size_t);
+ void *(*extra) (void *, size_t);
+ } chunkfun;
+ union
+ {
+ void (*plain) (void *);
+ void (*extra) (void *, void *);
+ } freefun;
+
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object : 1; /* There is a possibility that the current
@@ -189,11 +199,11 @@ extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
extern void _obstack_free (struct obstack *, void *);
extern int _obstack_begin (struct obstack *,
_OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
- void *(*)(size_t), void (*)(void *));
+ void *(*) (size_t), void (*) (void *));
extern int _obstack_begin_1 (struct obstack *,
_OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
- void *(*)(void *, size_t),
- void (*)(void *, void *), void *);
+ void *(*) (void *, size_t),
+ void (*) (void *, void *), void *);
extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
__attribute_pure__;
@@ -228,29 +238,31 @@ extern int obstack_exit_failure;
/* To prevent prototype warnings provide complete argument list. */
#define obstack_init(h) \
_obstack_begin ((h), 0, 0, \
- (void *(*)(size_t))obstack_chunk_alloc, \
- (void (*)(void *))obstack_chunk_free)
+ _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
+ _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \
- (void *(*)(size_t))obstack_chunk_alloc, \
- (void (*)(void *))obstack_chunk_free)
+ _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
+ _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
_obstack_begin ((h), (size), (alignment), \
- (void *(*)(size_t))(chunkfun), \
- (void (*)(void *))(freefun))
+ _OBSTACK_CAST (void *(*) (size_t), chunkfun), \
+ _OBSTACK_CAST (void (*) (void *), freefun))
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
_obstack_begin_1 ((h), (size), (alignment), \
- (void *(*)(void *, size_t))(chunkfun), \
- (void (*)(void *, void *))(freefun), (arg))
+ _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun), \
+ _OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
#define obstack_chunkfun(h, newchunkfun) \
- ((h)->chunkfun = (struct _obstack_chunk *(*)(void *, size_t))(newchunkfun))
+ ((void) ((h)->chunkfun.extra = _OBSTACK_CAST (void *(*) (void *, size_t), \
+ newchunkfun)))
#define obstack_freefun(h, newfreefun) \
- ((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))
+ ((void) ((h)->freefun.extra = _OBSTACK_CAST (void (*) (void *, void *), \
+ newfreefun)))
#define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
--
1.9.3
More information about the Libc-alpha
mailing list