From: RHEA::DECWRL::"elsie!ado@seismo.ARPA" 24-APR-1985 23:18 To: seismo!minow%rex.DEC@decwrl Subj: #if sizeof (int int) /* deserves a complaint! */ Received: from DECWRL by DEC-RHEA with SMTP; Wed, 24 Apr 85 20:16-PST Received: from seismo.ARPA (seismo.arpa.ARPA) by decwrl.ARPA (4.22.01/4.7.34) id AA16026; Wed, 24 Apr 85 20:16:02 pst Received: from elsie.UUCP by seismo.ARPA with UUCP; Wed, 24 Apr 85 23:15:05 EST Date: Wed, 24 Apr 85 23:15:05 EST Return-Path: Message-Id: <8504250415.AA27945@seismo.ARPA> Of course, the whole business of having "sizeof" in "#if" directives may be going by the boards, in which case the following changes are unnecessary. Anyway, they let you catch things like "#if sizeof (int int)" and also simplify things a bit. This is the output of "diff -c"; let me know if something else is more suitable (and is wanted). --ado *** cpp5.c.old Wed Apr 24 20:31:25 1985 --- cpp5.c Wed Apr 24 20:44:33 1985 *************** *** 152,157 typedef struct types { short type; /* This is the bit if */ char *name; /* this is the token word */ } TYPES; static TYPES basic_types[] = { --- 152,158 ----- typedef struct types { short type; /* This is the bit if */ char *name; /* this is the token word */ + short excluded; /* and these are illegal with it */ } TYPES; #define ANYSIGN (T_SIGNED|T_UNSIGNED) *************** *** 154,159 char *name; /* this is the token word */ } TYPES; static TYPES basic_types[] = { { T_CHAR, "char", }, { T_INT, "int", }, --- 155,164 ----- short excluded; /* and these are illegal with it */ } TYPES; + #define ANYSIGN (T_SIGNED|T_UNSIGNED) + #define ANYFLOAT (T_FLOAT|T_DOUBLE) + #define ANYINT (T_CHAR|T_SHORT|T_INT|T_LONG) + static TYPES basic_types[] = { T_CHAR, "char", ANYFLOAT | ANYINT, T_INT, "int", ANYFLOAT | ANYINT, *************** *** 155,169 } TYPES; static TYPES basic_types[] = { ! { T_CHAR, "char", }, ! { T_INT, "int", }, ! { T_FLOAT, "float", }, ! { T_DOUBLE, "double", }, ! { T_SHORT, "short", }, ! { T_LONG, "long", }, ! { T_SIGNED, "signed", }, ! { T_UNSIGNED, "unsigned", }, ! { 0, NULL, }, /* Signal end */ }; /* --- 160,174 ----- #define ANYINT (T_CHAR|T_SHORT|T_INT|T_LONG) static TYPES basic_types[] = { ! T_CHAR, "char", ANYFLOAT | ANYINT, ! T_INT, "int", ANYFLOAT | ANYINT, ! T_FLOAT, "float", ANYFLOAT | ANYINT | ANYSIGN, ! T_DOUBLE, "double", ANYFLOAT | ANYINT | ANYSIGN, ! T_SHORT, "short", ANYFLOAT | T_CHAR | T_SHORT | T_LONG, ! T_LONG, "long", ANYFLOAT | T_CHAR | T_SHORT | T_LONG, ! T_SIGNED, "signed", ANYFLOAT | ANYSIGN, ! T_UNSIGNED, "unsigned", ANYFLOAT | ANYSIGN, ! 0, NULL, 0 /* Signal end */ }; /* *************** *** 167,183 }; /* - * Test_table[] is used to test for illegal combinations. - */ - static short test_table[] = { - T_FLOAT | T_DOUBLE | T_LONG | T_SHORT, - T_FLOAT | T_DOUBLE | T_CHAR | T_INT, - T_FLOAT | T_DOUBLE | T_SIGNED | T_UNSIGNED, - T_LONG | T_SHORT | T_CHAR, - 0 /* end marker */ - }; - - /* * The order of this table is important -- it is also referenced by * the command line processor to allow run-time overriding of the * built-in size values. The order must not be changed: --- 172,177 ----- }; /* * The order of this table is important -- it is also referenced by * the command line processor to allow run-time overriding of the * built-in size values. The order must not be changed: *************** *** 534,539 cerror("#if sizeof, unknown type \"%s\"", token); return (OP_FAIL); } typecode |= tp->type; /* Or in the type bit */ } } --- 528,537 ----- cerror("#if sizeof, unknown type \"%s\"", token); return (OP_FAIL); } + if ((typecode & tp->excluded) != 0) { + cerror("#if ... sizeof: illegal type combination", NULLST); + return (OP_FAIL); + } typecode |= tp->type; /* Or in the type bit */ } } *************** *** 545,556 c = skipws(); } if (c == ')') { /* Last syntax check */ - for (testp = test_table; *testp != 0; testp++) { - if (!bittest(typecode & *testp)) { - cerror("#if ... sizeof: illegal type combination", NULLST); - return (OP_FAIL); - } - } /* * We assume that all function pointers are the same size: * sizeof (int (*)()) == sizeof (float (*)()) --- 543,548 ----- c = skipws(); } if (c == ')') { /* Last syntax check */ /* * We assume that all function pointers are the same size: * sizeof (int (*)()) == sizeof (float (*)()) *************** *** 585,606 nogood: unget(); cerror("#if ... sizeof() syntax error", NULLST); return (OP_FAIL); - } - - FILE_LOCAL int - bittest(value) - /* - * TRUE if value is zero or exactly one bit is set in value. - */ - { - #if (4096 & ~(-4096)) == 0 - return ((value & ~(-value)) == 0); - #else - /* - * Do it the hard way (for non 2's complement machines) - */ - return (value == 0 || value ^ (value - 1) == (value * 2 - 1)); - #endif } FILE_LOCAL int --- 577,582 ----- nogood: unget(); cerror("#if ... sizeof() syntax error", NULLST); return (OP_FAIL); } FILE_LOCAL int From: RHEA::DECWRL::"elsie!ado@seismo.ARPA" 29-APR-1985 08:52 To: seismo!minow%rex.DEC@decwrl Subj: int int--take 2 Received: from DECWRL by DEC-RHEA with SMTP; Fri, 26 Apr 85 17:57-PST Received: from seismo.ARPA (seismo.arpa.ARPA) by decwrl.ARPA (4.22.01/4.7.34) id AA07896; Fri, 26 Apr 85 17:57:34 pst Received: from elsie.UUCP by seismo.ARPA with UUCP; Fri, 26 Apr 85 20:56:38 EST Date: Fri, 26 Apr 85 20:56:38 EST Return-Path: Message-Id: <8504270156.AA06060@seismo.ARPA> The bad news is that the first try I sent you fouls up on things like #if sizeof (long int) == 4 The good news is that the version of the "basic_types" table below gets the above right. . .and also generates gripes about things like #if sizeof (int long) == 4 meaning that the comment about "int long" in the source can go. --ado static TYPES basic_types[] = { T_CHAR, "char", ANYFLOAT | ANYINT, T_INT, "int", ANYFLOAT | T_CHAR | T_INT, T_FLOAT, "float", ANYFLOAT | ANYINT | ANYSIGN, T_DOUBLE, "double", ANYFLOAT | ANYINT | ANYSIGN, T_SHORT, "short", ANYFLOAT | ANYINT, T_LONG, "long", ANYFLOAT | ANYINT, T_SIGNED, "signed", ANYFLOAT | ANYINT | T_CHAR | T_INT, T_UNSIGNED, "unsigned", ANYFLOAT | ANYINT | T_CHAR | T_INT, 0, NULL, 0 /* Signal end */ };