So here is the updated stack module. The name "CLEAR" has been changed to "DESTROY" as suggested by Bruno. Error checking has been included. The macro interface remains. Although a macro interface means macros, the macros are trivial and the type safety wins here, I think. I have renamed STACK_BASE to STACK_CURRENT_BASE because the base may be invalidated when items are pushed onto the stack and reallocation has to happen.
As I haven't heard anything from the FSF yet, I wouldn't mind if you considered the following in the public domain... #ifndef _GL_STACK_H #define _GL_STACK_H #include <stddef.h> #include <stdlib.h> #include "assure.h" #include "xalloc.h" #define STACK(type) \ struct { \ type *base; \ size_t size; \ size_t allocated; \ } #define STACK_INIT(stack) \ do \ { \ (stack).base = NULL; \ (stack).size = 0; \ (stack).allocated = 0; \ } \ while (0) #define STACK_DESTROY(stack) \ free ((stack).base) #define STACK_EMPTY(stack) \ ((stack).size == 0) #define STACK_CURRENT_BASE(stack) \ ((stack).base) #define STACK_PUSH(stack, item) \ do \ { \ if ((stack).size == (stack).allocated) \ (stack).base = x2nrealloc ((stack).base, &(stack).allocated, sizeof (item)); \ (stack).base [(stack).size++] = item; \ } \ while (0) #define STACK_POP(stack) \ (affirm (!STACK_EMPTY (stack)), (stack).base [--(stack).size]) #define STACK_DISCARD(stack) \ (affirm (!STACK_EMPTY (stack)), (--(stack).size)) #define STACK_TOP(stack) \ (affirm (!STACK_EMPTY (stack)), (stack).base[(stack).size - 1) #define STACK_SIZE(stack) \ ((stack).size) #endif /* _GL_STACK_H */ Am So., 24. Mai 2020 um 21:26 Uhr schrieb Bruno Haible <br...@clisp.org>: > > Paul Eggert wrote: > > I don't want to encourage programmers to supply an E with side effects, as > > side > > effects are trouble here. > > +1 >