Paul Eggert wrote: > If you look at the context of those lines in getgroups.c and > group-member.c, you'll see that those lines are OK. (So I'm afraid > the "sinner" is whoever's in charge of the rest. :-)
Yes. But in the group-member.c case, a macro that invokes xnmalloc would simplify your code as well. > partly, as I recall, because I'm not a big fan of function-like > macros that can't be implemented as functions. Yes, and also because by convention we use uppercase names for macros which are not function-like, and they make the source look weird. > Instead of changing xalloc.h, you could write this: > > struct foobartype *r = xnrealloc (r = NULL, 3, sizeof *r); Funny :-) But it relies on assignments inside a function argument... > XALLOC_WITH_EXPRESSION seems a bit tricky, since the expression > argument is evaluated in C++ but not in C. This can be fixed. See appended prototype. > I suppose the simplest thing to do would be to add what you're calling > XALLOC_WITH_TYPE Yes, I would prefer the XALLOC_WITH_TYPE macro over XALLOC_WITH_EXPRESSION because gbuf = XNMALLOC (n, GETGROUPS_T); is more explicit than gbuf = XNMALLOC (n, *gbuf); (And, remember, we have strict type checking: if the type argument of XNMALLOC is wrong, the C compiler will give a warning, and the C++ compiler will give an error.) > Something like this: > > #define XNMALLOC(n, t) ((t *) xnmalloc (n, sizeof (t))) > #define XCALLOC(n, t) ((t *) xcalloc (n, sizeof (t))) Yes, this looks good. I'll use these names. > This isn't right for an arbitrary C type name 't' due to C's bizarre > syntax for type names. It works for the most important types: 'char', typedef'ed names, 'struct something', and pointers to such types. It doesn't need to work for function pointers, because it's rare to use function pointers as array element type without a typedef. Bruno --------------------------------------------------------------------------- #include <stdlib.h> extern void * xmalloc (size_t n); extern void * xnmalloc (size_t n, size_t s); #define XALLOC_WITH_TYPE(N,TYPE) (TYPE *) xnmalloc (N, sizeof (TYPE)) #ifdef __cplusplus #define XALLOC_WITH_EXPRESSION(N,EXPR) xalloc_with_expression (N, &(EXPR)) template <typename T> inline T * xalloc_with_expression (size_t n, const T * expr) { return (T *) xnmalloc (n, sizeof (T)); } #else #define XALLOC_WITH_EXPRESSION(N,EXPR) xnmalloc (N, sizeof (EXPR)) #endif struct foo { int x; char y; }; struct foo * bar1 () { return XALLOC_WITH_TYPE (3, struct foo); } struct foo * bar2 (struct foo *p) { return XALLOC_WITH_EXPRESSION (3, *p); }