dhesi@bsu-cs.UUCP (Rahul Dhesi) (07/22/87)
#if 0 /* skip junk when compiling attached C program */ (I added comp.lang.c to the newsgroups and am directing followups there.) In article <8888@tekecs.TEK.COM> snoopy@doghouse.gwd.tek.com (Snoopy) writes: >In article <23741@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: >> There *should* either be a predicate built into the C >> preprocessor/compiler or a #define constant in some system include >> file; >YES! YES! Anyone for "LITTLE_ENDIAN" and "BIG_ENDIAN" ? And all the >predefines should be documented. [...] >But back to the main point, #ifdefs should reflect what you're >REALLY testing for. Use #ifdef LITTLE_ENDIAN, or #ifdef MASSBUS, >not #ifdef vax, or worse, some internal codename for a machine. Yes, PLEASE do not use machine names except in ONE place, where you select orthognoal attributes based on machine identity. Use the names of these attributes everywhere else. I hope the problem of writing software that will adapt itself to byte/word/int/long/short size and endianism and 1's vs 2's complement will be solved by the following program. The program can be compiled and executed from a makefile, and generates a series of defines that may then be included and tested by the remaining source files. Sample output when executed on a VAX-11/785 under 4.3BSD (I manually added the comments): #define Mch_Csz 8 /* size of char */ #define Mch_Ssz 16 /* size of short */ #define Mch_Isz 32 /* size of int */ #define Mch_Lsz 32 /* size of long */ #define Mch_LE 1 /* little-endian */ #define Mch_sgc 1 /* char may be signed */ John Cowan, the author, is somewhat unclear about the copyright status of this program. I suspect he really wanted it to be public domain, but wanted appropriate credit for it, so added the copyright notice. #endif /* skip junk */ /* The contents of the following program are copyright 1987 by John Cowan. It is hereby released to the public domain. This program emits C #define statements to the standard output describing the machine it is executing on. The following #defines are generated: Mch_Csz - size of a char, in bits Mch_Ssz - size of a short int, in bits Mch_Isz - size of a plain int, in bits Mch_Lsz - size of a long int, in bits Mch_BE - defined if the machine is big-endian; that is, if the most significant byte in a number appears first. Mch_LE - defined if the machine is little-endian; that is, if the least significant byte in a number appears first. Mch_PDP - defined if the machine uses PDP-11 byte ordering; LE for bytes-in-a-word and BE for words-in-a-long. Mch_ONE - defined if the machine uses one's complement arithmetic. Mch_sgc - defined if characters can be signed. */ #include <stdio.h> char bittest[6] = "\001\001\001\001\001"; char endtest[6] = "\001\002\003\004\005"; long be = 1; long le = 1; long pdp; int byteoff; int bytesize; long longval; main() { int i; byteoff = (*(int *) bittest & 2047) - 1; switch (byteoff) { case 256: bytesize = 8; break; case 512: bytesize = 9; break; case 1024: bytesize = 10; break; default: fprintf(stderr, "mch: bogus byte size\n"); exit(1); } printf("#define Mch_Csz %d\n", bytesize); printf("#define Mch_Ssz %d\n", sizeof(short) * bytesize); printf("#define Mch_Isz %d\n", sizeof(int) * bytesize); printf("#define Mch_Lsz %d\n", sizeof(long) * bytesize); longval = *(long *) endtest; for (i = 0; i < sizeof(long); i++) { be *= byteoff; be += endtest[i]; } for (i = sizeof(long) - 1; i >= 0; i--) { le *= byteoff; le += endtest[i]; } pdp = 0x02010403; if (longval == be) printf("#define Mch_BE 1\n"); else if (longval == le) printf("#define Mch_LE 1\n"); else if (longval == pdp) printf("#define Mch_PDP 1\n"); else { fprintf(stderr, "mch: bogus endianism\n"); exit(1); } if (~0 == 0) printf("#define Mch_ONE 1\n"); if ('\377' < 0) /* modified 1987/07/22 R. Dhesi */ printf("#define Mch_sgc 1\n"); } /* -- Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi */
abh@pogo.cray.com (Andy Hastings) (07/27/87)
In article <865@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > This program emits C #define statements to the standard output describing > the machine it is executing on. The following #defines are generated: > Mch_Csz - size of a char, in bits > Mch_Ssz - size of a short int, in bits > Mch_Isz - size of a plain int, in bits > Mch_Lsz - size of a long int, in bits > Mch_BE - defined if the machine is big-endian; that is, if > the most significant byte in a number appears first. > Mch_LE - defined if the machine is little-endian; that is, if > the least significant byte in a number appears first. > Mch_PDP - defined if the machine uses PDP-11 byte ordering; > LE for bytes-in-a-word and BE for words-in-a-long. > Mch_ONE - defined if the machine uses one's complement arithmetic. > Mch_sgc - defined if characters can be signed. Hmm. The program said `mch: bogus byte size' when I ran it on my CRAY X-MP. I changed the definition of bittest to: char bittest[9] = "\001\001\001\001\001\001\001\001"; and then I got the correct results: #define Mch_Csz 8 #define Mch_Ssz 64 #define Mch_Isz 64 #define Mch_Lsz 64 #define Mch_BE 1 Much better. -Andy Hastings ihnp4!cray!hall!abh Cray Research, Inc. sun!tundra!hall!abh *CRAY X-MP is a trademark of Cray Research, Inc.