C's Limited Macro Capabilities

Tom Stockfisch tps at chem.ucsd.edu
Thu Dec 7 19:25:23 AEST 1989


In article <62664 at aerospace.AERO.ORG> lmiller at batcomputer.UUCP (Lawrence H. Miller) writes:
>In article <69517 at psuecl.bitnet> bpm at psuecl.bitnet (Brian Moquin) writes:
>>        #define cast(flag,x)    #if flag=='I' \
>>                                        ((int)(x)) \
>>                                #elif flag=='F' \
>>                                        ((float)(x)) \
>>                                #endif
>>This is not legal C, but if it were I think it would enhance the power
>
>But for each such example, you can easily write a macro that
>is legal.

It is not always possible to write a legal macro, at least not easily.
For instance, suppose we want to define "nearest neighbors" of a lattice
with periodic boundary conditions (neighbors of the edges wrap around to
the other edge), and we want addressing to be very fast.

int	lat[DIM*DIM];

# define XNeighbor(i)	# if (i)%DIM == DIM-1
				( (i) - DIM + 1 )
			# else
				( (i) + 1 )

# define YNeighbor(i)	# if (i) >= DIM*(DIM - 1)
				( (i) + DIM  )
			# else
				( (i) - DIM*(DIM - 1) )

...
	switch (s)
	{
	case 0:	DoSomething( lat[XNeighbor(s)] + lat[YNeighbor(s)] );
		break;
	case 1:	DoSomething( lat[XNeighbor(s)] + lat[YNeighbor(s)] );
		break;
	...
	case DIM*DIM-1:	DoSomething( lat[XNeighbor(s)] + lat[YNeighbor(s)] );
		break;
	default: assert(0);
	}

When I have had to do this, I simply eliminate the "#" before the "if" and the
"else", and depend on the compiler to optimize out all of the branches that
can't be reached (in this case, half of them), and ignore the deluge of 
"constant in conditional context" warnings from lint.

M4 is usually of little or no help because too many C things are used
in the constant arithmetic.

-- 

|| Tom Stockfisch, UCSD Chemistry	tps at chem.ucsd.edu



More information about the Comp.lang.c mailing list