[net.sources] C side effect anomalies

buser@wanginst.UUCP (Jon Buser) (11/11/85)

    This is a fun program that can identify what C compiler was
used to compile it by analyzing side effect anomalies.  It illustrates
the variation in results obtained using different C compilers for
some syntactically valid, but unspecified, C expressions. For example
the C expression i = 1; j = i + i++; could leave j with the value 2, 3,
4, or 10 depending on what compiler was used.  Try it, but beware of
modifications!  Even minor changes to the program, such as adding print
statements, can change the results. 

------------------------- CUT HERE ---------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	whatcc.c
# This archive created: Mon Nov 11 13:33:46 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'whatcc.c'" '(3189 characters)'
if test -f 'whatcc.c'
then
	echo shar: will not over-write existing file "'whatcc.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'whatcc.c'
	X/* MODULE:      whatcc (what C compiler)                                */
	X/* PURPOSE:     whatcc uses known values for C side effects anomalies   */
	X/*              to determine what C compiler was used to compile the    */
	X/*              program.  The main purpose of the program is to         */
	X/*              illustrate the variability of these side effects.       */
	X/*                                                                      */
	X/* PROGRAMMER:  Jon Franklin Buser                                      */
	X/* DATE:        10/30/85                                                */
	X/* VERSION:     1.5                                                     */
	X/* REFERENCE:   McKeeman et al, Expression Side Effects in C,           */
	X/*              Wang Institute Technical Report TR-85-04                */
	X/* NOTE:        Minor modifications of the program can change the       */
	X/*              computed side effect values.                            */
	X/* RETURN ADDR: UUCP: decvax!wanginst!buser or decvax!wanginst!mckeeman */
	X/*              CSNET: buser@WangInst or mckeeman@WangInst              */
	X/* DISCLAIMER:  no guarantees are made                                  */
	X/* MODIFICATION HISTORY:                                                */
	X
	X/* Some compilers may need this include file                            */
	X/* #include <stdio.h>                                                   */
	X
	Xtypedef int Boole;
	X#define FALSE   ((Boole) 0)
	X#define TRUE    ((Boole) !FALSE)
	X
	X#define NUMCOMPS        5       /* Number of compilers                  */
	X#define NUMTESTS        5       /* Number of test cases                 */
	X
	Xchar   *whatcc ();
	X
	Xmain () {
	X    puts (whatcc ());
	X}
	X
	Xchar
	X       *whatcc () {
	X
	X    int     compiler;
	X    int     i;
	X    int     j;
	X    int     test;
	X    Boole match;
	X
	X    int     result[NUMTESTS];   /* array for computed test results      */
	X
	X    static int  comptab[NUMCOMPS][NUMTESTS] = {
	X        {4, 2, 2, 10, 4},       /* Berk C       */
	X        {3, 2, 3, 10, 4},       /* High C       */
	X        {3, 2, 3, 9, 3},        /* Wang C       */
	X        {4, 3, 3, 9, 4},        /* MrkW C       */
	X        {4, 3, 3, 12, 4}        /* VMS  C       */
	X    };
	X
	X    static char *cname[] = {
	X        "Berkeley 4.2BSD C",
	X        "MetaWare High C (version alpha 1.0)",
	X        "Wang VS C (version 01.03.00)",
	X        "Mark Williams C (version 2.4)",
	X        "VMS VAX-11 C (version 1.5-91)"
	X    };
	X
	X    static char *notfnd = "Compiler unknown";
	X
	X/* collect side-effect anomalies                                */
	X
	X    i = 1;
	X    j = i + ++i;
	X    result[0] = j;
	X
	X    i = 1;
	X    j = i + i++;
	X    result[1] = j;
	X
	X    i = 1;
	X    j = i++ + i++;
	X    result[2] = j;
	X
	X    i = 1;
	X    j = ++i + (++i + ++i);
	X    result[3] = j;
	X
	X    i = 1;
	X    j = i + (i = 2);
	X    result[4] = j;
	X
	X/* compare computed results to the table of precomputed results         */
	X
	X    for (compiler = 0; compiler < NUMCOMPS; compiler++) {
	X        for (match = TRUE, test = 0; test < NUMTESTS; test++) {
	X            match = match & (comptab[compiler][test] == result[test]);
	X        }
	X        if (match)
	X            return (cname[compiler]);
	X    }
	X
	X    return (notfnd);
	X
	X}
	X
	X
SHAR_EOF
if test 3189 -ne "`wc -c < 'whatcc.c'`"
then
	echo shar: error transmitting "'whatcc.c'" '(should have been 3189 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

-- 
Jon Franklin Buser        buser@WangInst
Wang Institute            decvax!wanginst!buser
Tyngsboro MA 01879

                    AND  

W. M. McKeeman            mckeeman@WangInst
Wang Institute            decvax!wanginst!mckeeman
Tyngsboro MA 01879