ok@quintus.UUCP (Richard A. O'Keefe) (04/13/88)
In article <1528@dataio.Data-IO.COM>, bright@Data-IO.COM (Walter Bright) writes: > Here is a portion of a package to handle bit vectors in C. It demonstrates > a reasonable use for allowing casts and sizeofs in preprocessor expressions. ... > /* This code depends on 8 bit bytes. Put check in for this. */ > /* I don't care about 1's complement machines. */ > #if (unsigned char) -1 != 255 > #error "bytes are not 8 bits" > #endif That has never been portable, if only because a great many C preprocessors do not support "#error". I tried something like this just now, and the entire error message was FOO.c: 1: undefined control May I point out that there is no need to do everything in the preprocessor? What distinguishes the C preprocessor from the incredibly hairy things in PL/I (compile-time procedures), Burroughs Algol, and SAIL (see TOPLAS some years ago), is that it is supposed to be small, fast, and cheap, so that you can afford to use it all the time whether you need it or not. If you need something more complicated than cpp can help with, you can use M4 (there is a public domain M4 in the mod.sources archives), or you can write a C program which generates a .h file or whatever. For example, consider an FFT routine. You don't want to call sin() and cos() at run time, but you can't rely on the compiler optimising cos(1.0/pow(2.0,6)) to a constant, and cpp can't do it. So you write a C program which calculates the table and writes out the appropriate constants. In this particular case, you might put something like real-prog: real-prog.c defs.h defs.h: mk-defs mk-defs >defs.h mk-defs: mk-defs.c in a make-file (there are versions of 'make' for MS-DOS and VMS), and the mk-defs.c program would have this test as perfectly ordinary C: if ((unsigned char)(-1) != 255) { fprintf(stderr, "unsigned char is not 8 bits\n"); exit(1); }