mjones@stdc01.UUCP (Michael Jones) (08/30/89)
I am interested in collecting popular pre-processor definitions. The
"semi-extensibility" which C offers via CPP provides an example set
for those curious about common usage, missing language features, etc.
Some ideas that I have seen or which seem useful to me would include:
1. Each of the high-precision numerical constants from the
back of Knuth's Art of Computer Programming, in appropriate
float/double real precision. In fact, since some compilers
fail slightly on floating input conversion, it might be
nice to see these numbers as "*(float *)" and "*(double *)"
indirections to explicit binary values stored as character
arrays of proper length, where "proper" rounding had been
used to construct them.
Definitions for ANSI Terminal control sequences and ASCII
control characters would also be useful. I use something like
this when writing for the IBM-PC to decode "keyboard scan-
codes":
#define SCAN_left_shift_key 0xNN (don't remember now)
#define SCAN_keypad_plus 0xNN
2. Variable and or type definitions. I have found explicit size
definitions to be handy:
#define ordinal_8 unsigned char
#define integer_8 char
:
:
#define ordinal_32 unsigned long
#define integer_32 long
3. Syntactic type definitions, ranging from the simple/suave to
the "ambitious". I have seen several versions of "improved"
selection statements, unbounded loops, sequential iterators,
and so on. Examples of this nature include:
a. IF/THEN/ELSE constructs:
#define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSEIF } else if (
#define ENDIF }
IF a == b THEN
x = 1;
b = 2;
ELSE
y = 3;
ENDIF
(If this example shocks you, arrange to view the S.R. Bourne "SH"
source code! Almost anyone would think it was in algol-60.)
b. SELECTION constructs:
#define when break; case
#define also case
#define otherwise break; default
switch (expression)
{
when value-1:
also value-2:
code;
when value-3:
code;
otherwise:
code;
}
c. UNBOUNDED ITERATION constructs:
#define ever 1
for (ever)
code;
#define repeat for (;;)
repeat
code;
4. Macro "pseudo-functions" from the simple and common min/max/abs:
#define min(a,b) ((a) > (b) ? (b) : (a))
to the more extreme "quick-sort generator given base data type"
which I have seen recently.
If you have anything like this which you would like to contribute to the
"C-Preprocessor Library", I would like to hear from you! Just think, that
handy little definition could be remembered for posterity as:
"... well son, back when *I* was a programmer, we used something
known as Galt's Device, a really nifty CPP definition that came
across the net. Of course, back then we had to ..."
where for Galt read *your name here*. I promise to share the full results
with everyone who submits something interesting. Or will post if there is
sufficient activity.
--
-- Michael T. Jones Email: ...!mcnc!rti!stdc01!mjones --
-- The wise man will pursue Paper: 3101-H Aileen Drive, Raleigh NC 27606 --
-- excellence in all things Voice: W:(919)361-3800 and H:(919)851-7979 --
hascall@atanasoff.cs.iastate.edu (John Hascall) (09/01/89)
In article <555@stdc01.UUCP> mjones@stdc01.UUCP (Michael Jones) writes: }I am interested in collecting popular pre-processor definitions. Probably everyone has re-invented some variation on: #define ALLOC(type) ((type *) malloc(sizeof(type))) As well as various constants: #define K_PI 3.141592653589793238462643 #define K_E 2.718281828459045235360287 #define K_PI_2 1.570796326794896619231322 #define K_PI_4 0.785398163397448309615661 #define K_PI_8 0.39269908169872415480783 #define K_PI_180 0.0174532925199432957692369 #define K_1_PI 0.3183098861837906715377675 #define K_2PI 6.283185307179586476925287 #define K_LN_2 0.693147180559945309417232 #define K_LN_3 1.098912288668109691395245 #define K_LN_10 2.302585092994045684017991 #define K_180_PI 57.295779513082320876798155 #define K_PI_180 0.017453292519943295769237 #define K_ARC_MINUTE 0.000290888208665721596154 #define K_ARC_SECOND 0.000004848136811095359936 Here is one I use on VMS where system calls return odd values for OK and even values for various errors (but which has a couple of ideas which could be applied elsewhere): #define ODD(x) ((x)&1) #define EVEN(x) (!ODD(x)) #define ERROR(cond) EVEN(cond) #define FATAL(str, val) exit((fprintf(stderr, "[%4d] 0x0%x <- %s\n", \ __LINE__, val, str), val)) #define SYSCALL(v, func) if (ERROR(v = func)) FATAL("func", v) Used like this for example: register int cond; SYSCALL(cond, SYS$ASSIGN(&device, &channel, 0, 0)); which gives error messages like: [ 17] 0x0908 <- SYS$ASSIGN(&device, &channel, 0, 0) No such device available (assuming the SYSCALL is on line 17)
scs@hstbme.mit.edu (Steve Summit) (09/03/89)
In article <1424@atanasoff.cs.iastate.edu> hascall@atanasoff.cs.iastate.edu.UUCP (John Hascall) writes: > Here is one I use on VMS where system calls return odd values for OK > and even values for various errors: > #define ODD(x) ((x)&1) > #define EVEN(x) (!ODD(x)) > #define ERROR(cond) EVEN(cond) If you do these right (I forget the exact form I used, but at least John's ODD macro would probably work) you can get the VAXC compiler to generate a single BLBS or BLBC instruction, those being two of the instructions (so the story goes) that the VAX hardware designers put in specifically at the request of the VMS software developers. (I try not to worry about such machine- level optimizations, but it's nice to know that, since the instructions are there, they're being used as intended.)
henry@utzoo.uucp (Henry Spencer) (09/06/89)
In article <555@stdc01.UUCP> mjones@stdc01.UUCP (Michael Jones) writes: > (If this example shocks you, arrange to view the S.R. Bourne "SH" > source code! Almost anyone would think it was in algol-60.) Modern versions of the Bourne shell have been fixed to get rid of those silly macros, which made the code a little bit harder to read and noticeably harder to use automatic tools on. -- V7 /bin/mail source: 554 lines.| Henry Spencer at U of Toronto Zoology 1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu