Macros that wrap
    Dan Olson 
    dano at ssc-vax.UUCP
       
    Fri Dec  1 07:03:17 AEST 1989
    
    
  
[ MACROS that Rap (Run D.M.C.) ]
One feature I really love from the lisp world is the ability to use
macros that wrap around a piece of code.  This lets the macro set up
an environment just during a given block of code.  Some examples of this
from the lisp world are:
	(with-open-file (f "some.file")
	    ;; Automatically closes the file when the block is exited.
	    )
	(without-interrupts
	    ;; Disables interrupts during a block of code.
	    )
Actually, most of lisp's control structures are not built in, but
are instead macros.
Anyhowz, this is a feature I miss in C and it's macro processor.  Does
anybody know of any work toward this feature?  I have found one way
of doing wraps using for(;;), but its often ugly and doesn't work
for all tasks.
(Example)
#include <stdio.h>
typedef char Bool;
#define TRUE 1
#define FALSE 0
#define WITH_FILE(f,n,o,e) \
	  for((f = fopen(n,o)) || (e = TRUE); f; fclose(f), f = NULL)
#define WITH_ARRAY(a,s) \
	  for(a = calloc(sizeof(*a),s); a; free(a), a = NULL)
void *calloc();
main()
{
  FILE *f;
  long *array;
  Bool error = FALSE;
  /* File is closed when the following block exits */
  WITH_FILE (f, "some.file", "r", error) {  
    /* read, read, read ... */
    }
  if (error) puts("Hey, you blew it.");
  /* Memory is free'ed when the following block exits */
  WITH_ARRAY (array, 10000) {
    puts("Got it!");
    /* Do something with all that memory */
    }
  return 0;
}
Ideally, if this feature exisited it would allow you to put any
arbitrary code before and after a given block including local
variable declarations, or operate on multiple blocks like the 
if {} else {} construct.
-- Side note --
I often "typedef char Bool" (and I think many others do too.), but
until recently I never got hit by the "1 out of 256" problem.  This
is when you begin to think of Bool as a real type and do things like:
status(ok_flag)
  Bool ok_flag;
{
  puts( ok_flag ? "Ok" : "Not Ok");
}
ptr = malloc(sizeof(*ptr));
status((Bool)ptr);		/* Not so good */
Instead of...
status((Bool)(ptr != NULL));	/* GOOD */
It's "1 out of 256", because the not so good method works only
when the lower byte of the pointer is non zero.
Dano
...!uw-beaver!ssc-vax (I think)
    
    
More information about the Comp.lang.c
mailing list