Unnecessary Macros (was Re: Unnecessary Parenthesis)

Dave Jones djones at megatest.UUCP
Thu Oct 6 08:17:13 AEST 1988


>From article <1527 at devsys.oakhill.UUCP>, by steve at oakhill.UUCP (steve):
> <1401 at devsys.oakhill.UUCP> <8629 at smoke.ARPA>
> 
> In case you don't remember, I was the one who first brought 
> up the use of temp in this discussion.  At that point in time the 
> discussion was the technique on writing macros, not the technique on 
> writing the macro square.  Most comments on why square is not 
> sane to write this way miss the point of the
> original discussion.  Square was just a trivial example...


Fair enough.  Things have gotten off the track a little.  I posted
a reply because I hate those silly little macros that send me poking
through .h files for no good reason, and fool my debugger.

Still, there are plenty of uses for macros, and YES!, even temps in
macros.

I have a memory allocation package that despenses memory packets of
a predetermined size.  It gets them wholesale from malloc, and then
keeps them in a linked list. It can improve the speed
of some kinds of programs very dramaticly, making some run hundreds
of times faster than they would if they called the libc's malloc()
for every heap-packet. (The malloc in Sun3 bsd 4.2, rel 3.4 libc gets 
slower and slower as heap usage increases, finally almost coming to a 
stop. I don't know why.)

The stategy helps so much that the procedure call overhead
for Heap_alloc() and Heap_free() can become significant.  So, in 
addition  to the regular proceudre versions (for debugging), the 
library provides two macros.  Problem is, they need a temp-variable 
for handling the free-list.  The solution is to define a "tmp" in 
the structure which defines the heap.

/*
** RCSHeader = $Header: heap.h,v 1.1 88/08/24 22:21:50 langmgr Exp $
** Copyright = Copyright (C) 1988 by Megatest Corporation All Rights Reserved
** TheAuthor = Dave Jones   (djones at goofy)
*/
#ifndef HEAP_H_

#include "smalloc.h"

typedef struct Heap_unit  
{
  struct Heap_unit* next;
  /* More memory allocated here... */
} Heap_Unit;

typedef struct heap  /* implements heap of packets of a fixed size */
{
  int packet_size;      /* in units of sizeof(Heap_unit) */
  int num_elements;     /* number of packets to allocate in next block */
  Heap_Unit* cache;     /* queue of all blocks of packets */
  Heap_Unit* next_free; /* free-list of packets */
  Heap_Unit* tmp;       /* temporary. used in alloc and free */
}Heap; 

extern Ptr Heap_underflow();

#define Heap_alloc(obj) \
  ((obj)->next_free == 0 ? \
      Heap_underflow(obj): \
      (Ptr) ( (obj)->tmp = (obj)->next_free, \
	      (obj)->next_free = (obj)->next_free->next, \
	      (obj)->tmp \
	    )   \
   )

#define Heap_free(obj,packet) \
 ((void)( (obj)->tmp = (obj)->next_free,  \
          (obj)->next_free = (Heap_Unit*)packet, \
          ((Heap_Unit*)packet)->next = (obj)->tmp \
        ) \
 )


/* allocate new heap */
extern Heap* Heap_new(/* size, init_size */)

/* dispose of heap allocated with Heap_new() */
void Heap_dispose(/* obj */)
/*   Heap *obj; */

/* Initialize a heap (static or automatic, for example) */
Heap* Heap_init(/* obj, size, init_size */)
/*  register Heap* obj; */

/* Clean up a heap initialized by Heap_init() */
extern Heap* Heap_clean(/* obj */);
/* register Heap* obj; */


#define HEAP_H_
#endif HEAP_H_



More information about the Comp.lang.c mailing list