Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!husc6!hao!ames!ptsfa!ihnp4!inuxc!iuvax!bsu-cs!dhesi
From: dhesi@bsu-cs.UUCP (Rahul Dhesi)
Newsgroups: comp.unix.wizards,comp.lang.c
Subject: Re: compiler predefines
Message-ID: <865@bsu-cs.UUCP>
Date: Wed, 22-Jul-87 12:34:23 EDT
Article-I.D.: bsu-cs.865
Posted: Wed Jul 22 12:34:23 1987
Date-Received: Sat, 25-Jul-87 11:02:09 EDT
References: <521@quacky.UUCP> <526@quacky.UUCP> <23741@sun.uucp> <8888@tekecs.TEK.COM>
Reply-To: dhesi@bsu-cs.UUCP (Rahul Dhesi)
Followup-To: comp.lang.c
Organization: CS Dept, Ball St U, Muncie, Indiana
Lines: 115
Summary: word size/endedness defines can be created at compile time
Xref: mnetor comp.unix.wizards:3390 comp.lang.c:3234

#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 

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
*/