Path: utzoo!attcan!uunet!peregrine!elroy!ames!mailrus!purdue!decwrl!megatest!djones From: djones@megatest.UUCP (Dave Jones) Newsgroups: comp.lang.c Subject: Re: Unnecessary Macros (was Re: Unnecessary Parenthesis) Message-ID: <866@goofy.megatest.UUCP> Date: 5 Oct 88 22:17:13 GMT References: <1527@devsys.oakhill.UUCP> Organization: Megatest Corporation, San Jose, Ca Lines: 95 From article <1527@devsys.oakhill.UUCP>, by steve@oakhill.UUCP (steve): > <1401@devsys.oakhill.UUCP> <8629@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_