Annotation of researchv10no/cmd/lcc/ph/c35.c, revision 1.1.1.1

1.1       root        1: /* The Plum Hall Validation Suite for C
                      2:  * Unpublished copyright (c) 1986-1991, Chiron Systems Inc and Plum Hall Inc.
                      3:  * VERSION: 4
                      4:  * DATE: 1993-01-01
                      5:  * The "ANSI" mode of this suite corresponds to official ANSI C, X3.159-1989.
                      6:  * As per your license agreement, your distribution is not to be moved or copied outside the Designated Site
                      7:  * without specific permission from Plum Hall Inc.
                      8:  */
                      9: 
                     10: #include "flags.h"
                     11: #ifndef SKIP35
                     12: /*
                     13:  * 3.5 - Declarations
                     14:  */
                     15: #include "defs.h"
                     16: 
                     17: 
                     18: 
                     19: 
                     20: static void c3_5_1();
                     21: static void c3_5_2();
                     22: static void c3_5_2_1();
                     23: static void c3_5_2_2();
                     24: static void c3_5_2_3();
                     25: static void c3_5_3();
                     26: static void c3_5_4();
                     27: static void c3_5_4_1();
                     28: static void c3_5_4_2();
                     29: static void c3_5_4_3();
                     30: static void c3_5_5();
                     31: static void c3_5_6();
                     32: static void c3_5_7();
                     33: extern void bitfields();
                     34: 
                     35: void c3_5()
                     36:        {
                     37:        Filename = "c35.c";
                     38:        c3_5_1();
                     39:        c3_5_2();
                     40:        c3_5_2_1();
                     41:        c3_5_2_2();
                     42:        c3_5_2_3();
                     43:        c3_5_3();
                     44:        c3_5_4();
                     45:        c3_5_4_1();
                     46:        c3_5_4_2();
                     47:        c3_5_4_3();
                     48:        c3_5_5();
                     49:        c3_5_6();
                     50:        c3_5_7();
                     51:        bitfields();
                     52:        }
                     53: 
                     54: 
                     55: /*
                     56:  * 3.5.1 - Storage-class specifiers
                     57:  */
                     58: #if ANSI
                     59: extern void (*pc3_5_2)() = c3_5_2;     /* extern allowed with initializer */
                     60: #else
                     61: void (*pc3_5_2)() = c3_5_2;
                     62: #endif
                     63: static void c3_5_1()
                     64:        {
                     65:        /* just check for existence of the keywords here */
                     66:        auto int i;
                     67:        register int j;
                     68:        static int k;
                     69:        extern int l;
                     70:        typedef int M;
                     71:        M m;
                     72: 
                     73:        i = j = k = l = m = 0;
                     74:        checkthat(__LINE__, !(i || j || k || l || m));
                     75:        checkthat(__LINE__, pc3_5_2 == c3_5_2);
                     76:        }
                     77: int l = 0;
                     78: 
                     79: 
                     80: 
                     81: 
                     82: 
                     83: 
                     84: 
                     85: 
                     86: 
                     87: 
                     88: 
                     89: 
                     90: 
                     91: 
                     92: 
                     93: 
                     94: 
                     95: 
                     96: 
                     97: 
                     98: 
                     99: 
                    100: 
                    101: 
                    102: 
                    103: /*
                    104:  * 3.5.2 - Type specifiers
                    105:  */
                    106: static void c3_5_2()
                    107:        {
                    108:        /* verify that all forms are handled */
                    109:        int x1;
                    110:        short int x2;
                    111:        short x3;
                    112:        long x4;
                    113:        int long x5;
                    114:        unsigned x6;
                    115:        int unsigned x7;
                    116:        char x8;
                    117: #if (ANSI || V7)
                    118:        UCHAR x9;
                    119:        USHORT x10;
                    120:        int USHORT x11;
                    121:        ULONG x12;
                    122:        ULONG int x13;
                    123: #endif
                    124: 
                    125: #if ANSI
                    126:        typedef int INT;
                    127:        typedef signed SIGNED;
                    128:        {
                    129:        signed char x14;
                    130:        short signed x15;
                    131:        short int signed x16;
                    132:        signed long x17;
                    133:        signed int long x18;
                    134:        signed x19;
                    135:        signed int x20;
                    136:        double long x21;
                    137:        const x22 = 22;
                    138:        int short const x23 = 23;
                    139:        volatile x24;
                    140:        long volatile int x25;
                    141:        const INT x26 = 26;
                    142:        INT volatile x27;
                    143:        INT const volatile x27a = 27;
                    144: 
                    145:        checkthat(__LINE__, sizeof(x24) == sizeof(int));
                    146:        }
                    147: #endif /* ANSI */
                    148: 
                    149: 
                    150: 
                    151: 
                    152: 
                    153: #if ANSI8712                                                                                                                                                   /* 3.5.2 (cont.) */
                    154: #define COMPATIBLE(t1, t2) { t1 v1={0}, *p1=&v1; t2 v2={0}, *p2=&v2; p1=p2; \
                    155:        checkthat(__LINE__, 0==mem_cmp((void *)p1, (void *)p2, sizeof(*p1))); }
                    156: #else
                    157: #define COMPATIBLE(t1, t2) { }
                    158: #endif
                    159: #if ANSI
                    160:        {
                    161:        struct s { int i:2; unsigned u:2; signed si:2; INT it:2; SIGNED st:2; } s = {-1, -1, -1, -1, -1};
                    162: 
                    163:        iequals(__LINE__, s.u, 3);
                    164:        iequals(__LINE__, s.si, -1);
                    165:        iequals(__LINE__, s.st, -1);
                    166: #if ANSI8804
                    167:        if (s.i == 3)                   /* if "plain int" bitfield is unsigned */
                    168:                iequals(__LINE__, s.it, 3);
                    169:        else if (s.i == -1)             /* else if "plain int" bitfield is signed */
                    170:                iequals(__LINE__, s.it, -1);
                    171:        else
                    172:                complain(__LINE__);     /* should take one of previous choices */
                    173: #endif /* ANSI8804 */
                    174: 
                    175:        COMPATIBLE(short, signed short);
                    176:        COMPATIBLE(short, signed short int);
                    177:        COMPATIBLE(unsigned short, unsigned short int);
                    178:        COMPATIBLE(int, signed int);
                    179:        COMPATIBLE(signed, signed int);
                    180:        COMPATIBLE(unsigned, unsigned int);
                    181:        COMPATIBLE(long, signed long);
                    182:        COMPATIBLE(long, signed long int);
                    183:        COMPATIBLE(unsigned long, unsigned long int);
                    184:        COMPATIBLE(long unsigned, long int unsigned);
                    185:        COMPATIBLE(short unsigned, unsigned int short);
                    186: 
                    187:        }
                    188: #endif /* ANSI */
                    189: 
                    190:        {
                    191:        float x28;
                    192:        double x29;
                    193:        void (*x30)();
                    194:        static x31 = 31;
                    195: 
                    196:        checkthat(__LINE__, sizeof(x31) == sizeof(int));
                    197:        iequals(__LINE__, x31, 31);
                    198:        }
                    199:        } /* end c3_5_2 */
                    200: 
                    201: 
                    202: 
                    203: /*
                    204:  * 3.5.2.1 - Structure and union specifiers.
                    205:  */
                    206: static void c3_5_2_1()
                    207:        {
                    208:        /* structures and unions have the same form */
                    209:        struct S1
                    210:                {
                    211:                char a;
                    212:                short b;
                    213:                int c;
                    214:                long d;
                    215:                float e;
                    216:                double f;
                    217:                unsigned g:1;
                    218:                } s;
                    219: 
                    220:        union U1
                    221:                {
                    222:                char u1_a;
                    223:                short u1_b;
                    224:                int u1_c;
                    225:                unsigned u1_d;
                    226:                long u1_e;
                    227:                float u1_f;
                    228:                double u1_g;
                    229: #if (ANSI || V7)
                    230:                UCHAR u1_h;
                    231:                USHORT u1_i;
                    232:                ULONG  u1_j;
                    233: #endif
                    234: #if ANSI
                    235:                signed char u1_k;
                    236:                long double u1_l;
                    237: #endif
                    238:                } u, *pu = &u;
                    239: 
                    240: #if (ANSI || UNIQ_MEMB_NAMES)
                    241:        struct uniqnames
                    242:                {
                    243:                double a;
                    244:                };
                    245: #endif
                    246: 
                    247:        struct
                    248:                {
                    249:                unsigned x:1;
                    250:                } onefield;
                    251: 
                    252: 
                    253:                                                                                                                                                                                /* 3.5.2.1 (cont.) */
                    254:        struct
                    255:                {
                    256:                unsigned fa_f:1;
                    257:                unsigned     :0;        /* break storage boundry */
                    258:                unsigned fa_g:1;
                    259:                } forcealign;
                    260: #if ANSI
                    261:        union ufields
                    262:                {
                    263:                unsigned x1 : 1;
                    264:                unsigned x3 : 2+1;
                    265:                } uf1;
                    266:        enum { ONE=1, TWO };
                    267: #endif /* ANSI */
                    268: 
                    269:        struct fields
                    270:                {
                    271:                unsigned x1:1;
                    272:                unsigned x2:2;
                    273:                unsigned x3:3;
                    274:                unsigned   :1;          /* just because it can be done */
                    275:                unsigned x4:4;
                    276: #if ANSI
                    277:                int      x5:'\2'; /* char-constant width */
                    278:                signed int x6:TWO; /* enum width */
                    279: #endif /* ANSI */
                    280:                } b, b2, *p = &b2;
                    281: 
                    282: #if !ANSI
                    283:        checkthat(__LINE__, sizeof(onefield) == sizeof(unsigned));
                    284: #endif
                    285: 
                    286: #if ANSI
                    287:        b.x6 = -1;
                    288:        dequals(__LINE__, (double)b.x6, -1.);
                    289: #endif
                    290:        b2.x4 = 0;
                    291:        b.x1 = p->x1 = 1;
                    292:        p->x2 = b.x1 + 2*p->x1;
                    293:        b.x3 = p->x2 + 4*b.x1;
                    294:        p->x4 += (b.x3 - b.x1) * p->x2; /* unsigned wraparound (3.2.1.1) */
                    295:        iequals(__LINE__, b.x1, 1); 
                    296:        iequals(__LINE__, p->x2, 3); 
                    297:        iequals(__LINE__, b.x3, 7); 
                    298:        iequals(__LINE__, p->x4, 2); 
                    299: 
                    300: 
                    301: 
                    302: 
                    303:        /* any interactions? */                                                                                                                         /* 3.5.2.1 (cont.) */
                    304:        b.x2 = p->x3 = b.x4 = 0;
                    305:        iequals(__LINE__, b.x1, 1); 
                    306:        iequals(__LINE__, p->x2, 3); 
                    307:        iequals(__LINE__, b.x3, 7); 
                    308:        iequals(__LINE__, p->x4, 2); 
                    309: 
                    310: 
                    311:        /* unsigned values convert modulo largest+1 */
                    312:        b.x1 = 2;
                    313:        b.x2 = 4;
                    314:        b.x3 = 8;
                    315:        b.x4 = 16;
                    316:        iequals(__LINE__, b.x1, 0); 
                    317:        iequals(__LINE__, b.x2, 0); 
                    318:        iequals(__LINE__, b.x3, 0); 
                    319:        iequals(__LINE__, b.x4, 0); 
                    320: 
                    321:        /* there are not very many things about fields that are not
                    322:        * implementation dependent. 
                    323:        * 
                    324:        */
                    325:        checkthat( - __LINE__, sizeof(forcealign) >= 2 * sizeof(onefield));
                    326: 
                    327:        /* size of union is size of greatest element (+ padding?) */
                    328:        checkthat(__LINE__, sizeof(u) >= sizeof(double));
                    329: #if ANSI
                    330:        checkthat(__LINE__, sizeof(u) >= sizeof(long double));
                    331: #endif
                    332:        /* make sure all union members are accessible and have the right value */
                    333: #if SIGNED_CHAR
                    334:        u.u1_a = -1;
                    335:        iequals(__LINE__, u.u1_a, -1);
                    336: #else
                    337:        u.u1_a = 255;
                    338:        iequals(__LINE__, u.u1_a, 255);
                    339: #endif
                    340:        pu->u1_b = -1;
                    341:        iequals(__LINE__, u.u1_b, -1);
                    342:        u.u1_c = -2;
                    343:        iequals(__LINE__, u.u1_c, -2);
                    344:        u.u1_d = MAX_UINT;
                    345:        checkthat(__LINE__, u.u1_d == MAX_UINT);
                    346:        u.u1_e = -1;
                    347:        lequals(__LINE__, u.u1_e, -1L);
                    348:        u.u1_f = 1.0;
                    349:        dequals(__LINE__, u.u1_f, 1.0);
                    350:        u.u1_g = 2.2;
                    351:        dequals(__LINE__, u.u1_g, 2.2);
                    352: 
                    353:                                                                                                                                                                                /* 3.5.2.1 (cont.) */
                    354: 
                    355: 
                    356: 
                    357: 
                    358: 
                    359: 
                    360: #if ANSI
                    361:        u.u1_h = MAX_UCHAR;
                    362:        iequals(__LINE__, u.u1_h, MAX_UCHAR);
                    363:        u.u1_i = MAX_USHORT;
                    364:        checkthat(__LINE__, u.u1_i == MAX_USHORT);
                    365:        u.u1_j = MAX_ULONG;
                    366:        checkthat(__LINE__, u.u1_j == MAX_ULONG);
                    367: 
                    368:        u.u1_k = -1;
                    369:        iequals(__LINE__, u.u1_k, -1);
                    370:        u.u1_l = 3.3L;
                    371:        ldequals(__LINE__, u.u1_l, 3.3L);
                    372: 
                    373: #endif
                    374: 
                    375:        /* addresses of members must be monotonically increasing */
                    376:        checkthat(__LINE__, (char *)&s.a < (char *)&s.b);
                    377:        checkthat(__LINE__, (char *)&s.b < (char *)&s.c);
                    378:        checkthat(__LINE__, (char *)&s.c < (char *)&s.d);
                    379:        checkthat(__LINE__, (char *)&s.d < (char *)&s.e);
                    380:        checkthat(__LINE__, (char *)&s.e < (char *)&s.f);
                    381: 
                    382:        /* also, the address of the first member is the address of the structure */
                    383:        checkthat(__LINE__, (char *)&s.a == (char *)&s);
                    384: 
                    385:        /* structs and unions are padded, to allow array alignment */
                    386:        {
                    387:        struct S1 as[2];
                    388:        union U1 au[2];
                    389: 
                    390:        checkthat(__LINE__, &as[1] == (struct S1 *)(sizeof(struct S1) + (char *)&as[0]));
                    391:        checkthat(__LINE__, &au[1] == (union U1 *)(sizeof(union U1) + (char *)&au[0]));
                    392:        }
                    393:        } /* end c3_5_2_1 */
                    394: 
                    395: 
                    396: 
                    397: 
                    398: 
                    399: 
                    400: 
                    401: 
                    402: 
                    403: /*
                    404:  * 3.5.2.2 - Enumeration specifiers
                    405:  */
                    406: static void c3_5_2_2()
                    407:        {
                    408:        int i;
                    409: #if (V7 || ANSI)
                    410:        /* number from 0 */
                    411:        enum a { a0, a1, a2, a3} aset;
                    412: 
                    413:        /* number explicitly, with the order picked up in the middle */
                    414:        enum b { b2=2, b1=1, b0=0, b1a, b2a, b2b=2} bset, *pbset;
                    415: 
                    416:        /* check aset */
                    417:        iequals(__LINE__, a0, 0);
                    418:        iequals(__LINE__, a1, 1);
                    419:        iequals(__LINE__, a2, 2);
                    420:        iequals(__LINE__, a3, 3);
                    421: 
                    422:        /* check bset */
                    423:        iequals(__LINE__, b2, 2);
                    424:        iequals(__LINE__, b1, 1);
                    425:        iequals(__LINE__, b0, 0);
                    426:        iequals(__LINE__, b1a, 1);
                    427:        iequals(__LINE__, b2a, 2);
                    428:        iequals(__LINE__, b2b, 2);
                    429: 
                    430:        /* before ANSI the use of enums was limited */
                    431:        bset = b2a;
                    432:        pbset = &bset;
                    433:        iequals(__LINE__, bset, b2a);
                    434:        checkthat(__LINE__, bset==b2a);
                    435:        checkthat(__LINE__, bset!=b1);
                    436:        iequals(__LINE__, *pbset, bset);
                    437: 
                    438: 
                    439: 
                    440: 
                    441: 
                    442: 
                    443: 
                    444: 
                    445: 
                    446: 
                    447: 
                    448: 
                    449: 
                    450: 
                    451: 
                    452: 
                    453:                                                                                                                                                                                /* 3.5.2.2 (cont.) */
                    454:        /* with ANSI, enums can be used anywhere an int can be used */
                    455: #if ANSI
                    456:        {
                    457:        int a[b2b] = { 0, 1 };
                    458: 
                    459:        iequals(__LINE__, a[b0], ivalue(0));
                    460:        switch (bset)
                    461:                {
                    462:                case b0:
                    463:                        i = 999;
                    464:                        break;
                    465:                case b2:
                    466:                        i = 0;
                    467:                        break;
                    468:                default :
                    469:                        i = 999;
                    470:                        break;
                    471:                case a1:
                    472:                        /* not wise, but possible */
                    473:                        i = 999;
                    474:                        break;
                    475:                }
                    476:        iequals(__LINE__, i, 0);
                    477: 
                    478:        iequals(__LINE__, ++bset, 3);
                    479:        checkthat(__LINE__, sizeof(aset) <= sizeof(int));
                    480:        }
                    481: #endif /* ANSI */
                    482: #endif /* V& || ANSI */
                    483:        } /* end c3_5_2_2 */
                    484: 
                    485: 
                    486: 
                    487: 
                    488: 
                    489: 
                    490: 
                    491: 
                    492: 
                    493: 
                    494: 
                    495: 
                    496: 
                    497: 
                    498: 
                    499: 
                    500: 
                    501: 
                    502: 
                    503: /* 
                    504:  * 3.5.2.3 - Tags.
                    505:  */
                    506: 
                    507: /* mutually-referencing structures */
                    508: struct mutrefa                                                         /* mutrefa is "tag" */
                    509:        {                                                                       /* followed by "{ struct-decl-list }" */
                    510:        struct mutrefb *refb;                           /* "incomplete structure spec" for ptr-to-struct */
                    511:        int vala;
                    512:        };
                    513: struct mutrefb 
                    514:        {
                    515:        struct mutrefa *refa;                           /* uses previously-decl "tag" */
                    516:        int valb;
                    517:        };
                    518: #if ANSI
                    519: struct mutrefb strb;                                   /* "tentative def" -- 3.7.2 */
                    520: #else
                    521: extern struct mutrefb strb;                            /* ordinary "extern" ref */
                    522: #endif
                    523: struct mutrefa stra = { &strb, 11};
                    524: struct mutrefb strb = { &stra, 13};
                    525: /* "incomplete structure spec" must work for typedefs */
                    526: typedef struct s2 S2;  /* "incomplete structure spec" for typedef */
                    527: struct s2                              /* must be "completed" before size is needed */
                    528:        {
                    529:        struct s2 * ps1;        /* "incomplete spec" ok for ptr-to-struct */
                    530:        S2 *ps2;                        /* so is the equivalent typedef */
                    531:        int val;
                    532:        } x1;                           /* "tentative def" of x1 */
                    533: S2 x2;                                 /* "tentative def" of x2 */
                    534: 
                    535: #if ANSI
                    536: /* "incomplete structure spec" must work for functions returning structures */
                    537: struct s3 rets3();
                    538: struct s3                      /* "incomplete spec" must be completed before size is needed */
                    539:        {
                    540:        int s3_1, s3_2, s3_3, s3_4;
                    541:        } R3 = {1, 2, 3, 4};
                    542: 
                    543: 
                    544: 
                    545: 
                    546: 
                    547: 
                    548: 
                    549: 
                    550: 
                    551: 
                    552: 
                    553:                                                                                                                                                                        /* 3.5.2.3 (cont.) */
                    554: /* watch out for nested scope in structure tag ... */
                    555: typedef struct nest NEST;
                    556: struct s3 rets3() 
                    557:        {                               /* introduces new block scope */
                    558:        /* should be ignored by typedef NEST */
                    559:        struct nest { int a, b;};
                    560: 
                    561:        /* use "vacuous structure spec" to disambiguate */
                    562:        struct mutrefb; /* introduces new tag */
                    563:        struct mutrefa 
                    564:                {
                    565:                struct mutrefb *refb;
                    566:                };
                    567:        struct mutrefb 
                    568:                {
                    569:                struct mutrefa *refa;
                    570:                };
                    571:        return R3;
                    572:        }
                    573: struct nest            /* completing the spec from typedef NEST */
                    574:        {
                    575:        int nest_1;
                    576:        int nest_2;
                    577:        } Nest = { 1, 2};
                    578: #endif
                    579: 
                    580: 
                    581: 
                    582: 
                    583: 
                    584: 
                    585: 
                    586: 
                    587: 
                    588: 
                    589: 
                    590: 
                    591: 
                    592: 
                    593: 
                    594: 
                    595: 
                    596: 
                    597: 
                    598: 
                    599: 
                    600: 
                    601: 
                    602: 
                    603:                                                                                                                                                                                /* 3.5.2.3 (cont.) */
                    604: /* mutually-referencing unions */
                    605: union mutrefua                                                         /* mutrefua is "tag" */
                    606:        {                                                                       /* followed by "{ union-decl-list }" */
                    607:        union mutrefub *refub;                          /* "incomplete union spec" for ptr-to-union */
                    608:        int vala;
                    609:        };
                    610: union mutrefub 
                    611:        {
                    612:        union mutrefua *refua;                          /* uses previously-decl "tag" */
                    613:        int valb;
                    614:        };
                    615: #if ANSI
                    616: union mutrefub unb;                                    /* "tentative def" -- 3.7.2 */
                    617: union mutrefua una = { &unb };
                    618: union mutrefub unb = { &una };
                    619: #else
                    620: extern union mutrefub unb;                             /* ordinary "extern" ref */
                    621: union mutrefua una;
                    622: union mutrefub unb;
                    623: #endif
                    624: /* "incomplete union spec" must work for typedefs */
                    625: typedef union u2 U2;   /* "incomplete union spec" for typedef */
                    626: union u2                               /* must be "completed" before size is needed */
                    627:        {
                    628:        union u2 * pu1; /* "incomplete spec" ok for ptr-to-union */
                    629:        U2 *pu2;                        /* so is the equivalent typedef */
                    630:        int val;
                    631:        } ux1;                          /* "tentative def" of ux1 */
                    632: U2 ux2;                                        /* "tentative def" of ux2 */
                    633: 
                    634: #if ANSI
                    635: /* "incomplete union spec" must work for functions returning unions */
                    636: union u3 retu3();
                    637: union u3                       /* "incomplete spec" must be completed before size is needed */
                    638:        {
                    639:        int u3_1; char u3_2;
                    640:        } U3 = {1};
                    641: 
                    642: 
                    643: 
                    644: 
                    645: 
                    646: 
                    647: 
                    648: 
                    649: 
                    650: 
                    651: 
                    652: 
                    653:                                                                                                                                                                                /* 3.5.2.3 (cont.) */
                    654: /* watch out for nested scope in union tag ... */
                    655: typedef union unest UNEST;
                    656: union u3 retu3() 
                    657:        {                               /* introduces new block scope */
                    658:        /* should be ignored by typedef UNEST */
                    659:        union unest { int a, b;};
                    660: 
                    661:        /* use "vacuous union spec" to disambiguate */
                    662:        union mutrefub; /* introduces new tag */
                    663:        union mutrefua 
                    664:                {
                    665:                union mutrefub *refub;
                    666:                };
                    667:        union mutrefub 
                    668:                {
                    669:                union mutrefua *refua;
                    670:                };
                    671:        return U3;
                    672:        }
                    673: union unest            /* completing the spec from typedef UNEST */
                    674:        {
                    675:        int unest_1;
                    676:        float unest_2;
                    677:        } UNest = { 1 };
                    678: #endif /* ANSI */
                    679: 
                    680: 
                    681: 
                    682: 
                    683:                                                                                                                                                                                /* 3.5.2.3 (cont.) */
                    684: static void c3_5_2_3() 
                    685:        {
                    686:        char *p = 0;            /* This ptr will be used to test ptr-to-struct cast */
                    687:        /* make declarations using struct/union tags */
                    688:        struct s1 
                    689:                {
                    690:                int a, b, c;    /* unique struct member name spaces were tested in 3.1.2.3; */
                    691:                };                              /* here we use K&R-compatible name rules */
                    692:        struct s1 a, b, c;
                    693:        union u1 
                    694:                {
                    695:                int i;
                    696:                double d;
                    697:                };
                    698: 
                    699: 
                    700: 
                    701: 
                    702: 
                    703:                                                                                                                                                                                /* 3.5.2.3 (cont.) */
                    704:        union u1 u1;
                    705: 
                    706:        auto struct astr        /* test syntax of stor-cl with struct */
                    707:                {
                    708:                int a;
                    709:                } astr;
                    710: 
                    711:        static struct astr sstr = {123};
                    712: 
                    713:        /* make sure that they exist */
                    714:        a.a = 1;
                    715:        iequals(__LINE__, a.a, 1);      /* (auto) local struct holds proper value */
                    716:        u1.i = 2;
                    717:        iequals(__LINE__, u1.i, 2);     /* (auto) local union holds proper value */
                    718: 
                    719:        /* make sure forward references work (see x1 and x2 on prev page) */
                    720:        x1.val = 3;
                    721:        x2.val = 4;
                    722:        x2.ps1 = &x1;
                    723:        x2.ps2 = &x2;           /* points to itself !! */
                    724:        iequals(__LINE__, x2.ps1->val, 3);      /* ptr-to-struct in struct works */
                    725:        iequals(__LINE__, x2.ps2->val, 4);      /* ptr-to-struct in struct works */
                    726: 
                    727:        /* unions can accept and hold properly-typed values */
                    728:        ux1.val = 3;
                    729:        ux2.val = 4;
                    730:        iequals(__LINE__, ux1.val, ivalue(3));
                    731:        iequals(__LINE__, ux2.val, ivalue(4));
                    732:        ux2.pu1 = &ux1;
                    733:        aequals(__LINE__, (char *)ux2.pu1, (char *)avalue(&ux1));
                    734: 
                    735:        /* mutually-referencing structs */
                    736:        iequals(__LINE__, stra.vala, 11);
                    737:        iequals(__LINE__, strb.valb, 13);
                    738:        iequals(__LINE__, stra.refb->valb, 13);
                    739:        iequals(__LINE__, strb.refa->vala, 11);
                    740: #if ANSI
                    741:        /* mutually-referencing unions */
                    742:        aequals(__LINE__, (char *)una.refub, (char *)avalue(&unb));
                    743:        aequals(__LINE__, (char *)unb.refua, (char *)avalue(&una));
                    744: #endif
                    745:        /* astr and sstr are different */
                    746:        astr.a = 1;
                    747:        iequals(__LINE__, sstr.a, 123);
                    748: 
                    749: 
                    750: 
                    751: 
                    752: 
                    753:                                                                                                                                                                                /* 3.5.2.3 (cont.) */
                    754: #if ANSI
                    755:        iequals(__LINE__, Nest.nest_2, 2);      /* test that block-local "nest" was not */
                    756:        iequals(__LINE__, rets3().s3_4, 4);     /* seen outside its block */
                    757: 
                    758:        /* A cast (3.3.4) uses a "type-name" (3.5.5), which can decl a tag */
                    759:        p = (char *)(struct incast { int a; int b; } * )p;      /* decls tag "incast" */
                    760:        checkthat(__LINE__, sizeof(struct incast) > 0);         /* test that struct incast decl'ed properly */
                    761: 
                    762:        {
                    763:        struct s1;      /* new scope */
                    764:        struct s1 { char c; } sc;
                    765: 
                    766:        sc.c = ivalue('a');
                    767:        iequals(__LINE__, sc.c, 'a');
                    768:        }
                    769: 
                    770: #endif /* ANSI */
                    771:        } /* end c3_5_2_3 */
                    772: 
                    773: 
                    774: 
                    775: 
                    776: 
                    777: 
                    778: 
                    779: 
                    780: 
                    781: 
                    782: 
                    783: 
                    784: 
                    785: 
                    786: 
                    787: 
                    788: 
                    789: 
                    790: 
                    791: 
                    792: 
                    793: 
                    794: 
                    795: 
                    796: 
                    797: 
                    798: 
                    799: 
                    800: 
                    801: 
                    802: 
                    803: /*
                    804:  * 3.5.3 - const and volatile
                    805:  */
                    806: static void c3_5_3()
                    807:        {
                    808: #if ANSI
                    809:        const char c1;
                    810:        const UCHAR c2;
                    811:        const signed char c3;
                    812:        const short c4;
                    813:        const USHORT c5;
                    814:        const int c6;
                    815:        const unsigned int c7;
                    816:        const long c8;
                    817:        const ULONG c9;
                    818:        const float c10;
                    819:        const double c11;
                    820:        const long double c12;
                    821:        volatile char v1;
                    822:        volatile UCHAR v2;
                    823:        volatile signed char v3;
                    824:        volatile short v4;
                    825:        volatile USHORT v5;
                    826:        volatile int v6;
                    827:        volatile unsigned int v7;
                    828:        volatile long v8;
                    829:        volatile ULONG v9;
                    830:        volatile float v10;
                    831:        volatile double v11;
                    832:        volatile long double v12;
                    833:        volatile int * const cv1;
                    834:        const int * volatile cv2;
                    835:        int *pi;
                    836:        int i;
                    837:        const int *pci = &i;    /* may be assigned */
                    838:        volatile int *pvi = &i;
                    839:        const struct sa { int i; } csa;
                    840:        struct sa sa2;          /* doesn't inherit const */
                    841: 
                    842:        pi = (int *)pci;        /* ok with cast */
                    843:        checkthat(__LINE__, pi == &i);
                    844:        pi = (int *)pvi;
                    845:        checkthat(__LINE__, pi == &i);
                    846:        sa2.i = 1;              /* ok, not const */
                    847:        iequals(__LINE__, sa2.i, 1);
                    848:        COMPATIBLE(volatile int, int volatile);
                    849:        COMPATIBLE(signed volatile int, int volatile);
                    850:        COMPATIBLE(short volatile, signed volatile short int);
                    851: 
                    852: #endif /* ANSI */
                    853:        } /* end c3_5_3 */
                    854: 
                    855: 
                    856: /*
                    857:  * 3.5.4 - Declarators
                    858:  */
                    859: typedef int INT;
                    860: int func1() { return 7;}
                    861: INT func2() { return 11;}
                    862: int (*fpfi1())(){return func1;}                /* func ret ptr to func ret int */
                    863: typedef int (*PFI)();                          /* ptr to func ret ptr to int */
                    864: PFI fpfi2(){return func2;}                     /* func ret ptr to func ret int */
                    865: static void c3_5_4()
                    866:        {
                    867:        /* 2d-arr of ptr to func ret ptr to func ret int */
                    868:        int (*(*apfpfi1[2][3])())();
                    869:        int i, j;
                    870:        int *p1 = &i;
                    871:        int (*p2);
                    872:        int ((*p3));    /* declarator in parens is identical to unadorned */
                    873:        int (func1)();  /* declarator in parens is identical to unadorned */
                    874: 
                    875:        /* try the same thing with typedefs */
                    876:        typedef PFI (*PFPFI)();         /* ptr to func ret ptr to func ret int */
                    877:        PFPFI apfpfi2[2][3];
                    878: 
                    879:        p2 = (int *)avalue(p1);
                    880:        p3 = p2;
                    881:        checkthat(__LINE__, p3 == p1);
                    882:        apfpfi1[1][2] = fpfi1;
                    883:        apfpfi2[1][2] = fpfi2;
                    884:        i = 1, j = 2;
                    885:        iequals(__LINE__,  (*(*apfpfi1[i][j])())(), 7);
                    886:        iequals(__LINE__,  (*(*apfpfi2[i][j])())(), 11);
                    887: 
                    888: #if ANSI
                    889:        {
                    890:        struct { int i1; const int i2; } x = { 1, 2 };
                    891: 
                    892:        x.i1 = ivalue(3);       /* not const */
                    893:        iequals(__LINE__, x.i1, 3);
                    894:        }
                    895: #endif /* ANSI */
                    896:        } /* end c3_5_4 */
                    897: 
                    898: 
                    899: 
                    900: 
                    901: 
                    902: 
                    903: 
                    904: /*
                    905:  * 3.5.4.1 - Pointer declarators
                    906:  */
                    907: static void c3_5_4_1()
                    908:        {
                    909:        char c = 'x';
                    910:        char *pc = &c;
                    911:        char **ppc = &pc;
                    912:        char ***pppc = &ppc;
                    913:        char ****ppppc = &pppc;
                    914:        char *****pppppc = &ppppc;
                    915:        char ******ppppppc = &pppppc;
                    916:        typedef char C;
                    917:        typedef C *PC;
                    918:        typedef PC *PPC;
                    919:        typedef PPC *PPPC;
                    920:        typedef PPPC *PPPPC;
                    921:        typedef PPPPC *PPPPPC;
                    922:        typedef PPPPPC *PPPPPPC;
                    923:        C d = 'y';
                    924:        PC pd = &d; 
                    925:        PPC ppd = &pd; 
                    926:        PPPC pppd = &ppd; 
                    927:        PPPPC ppppd = &pppd; 
                    928:        PPPPPC pppppd = &ppppd; 
                    929:        PPPPPPC ppppppd = &pppppd; 
                    930: 
                    931: #if ANSI
                    932:        const char *pconst = "constant string literal";
                    933:        char carray[] = "variable string literal"; char *const constp = carray;
                    934:        volatile int *vp = 0;
                    935:        const char * volatile * pvpconst = &pconst;
                    936: 
                    937:        ++pconst;
                    938:        iequals(__LINE__, *pconst, 'o');
                    939:        ++*constp;
                    940:        iequals(__LINE__, *constp, 'v'+1);
                    941:        vp;
                    942:        iequals(__LINE__, **pvpconst, 'o');
                    943:        {        /* Now test that volatile int * and int signed volatile * are compatible... */
                    944:        volatile int        *v1={0}, **p1=&v1;
                    945:        int signed volatile *v2={0}, **p2=&v2;
                    946:        p1=p2;
                    947:        checkthat(__LINE__, 0==mem_cmp((void *)p1, (void *)p2, sizeof(*p1)));
                    948:        }
                    949: #endif
                    950:        iequals(__LINE__, ******ppppppc, 'x');
                    951:        iequals(__LINE__, ******ppppppd, 'y');
                    952:        } /* end c3_5_4_1 */
                    953: 
                    954: /*
                    955:  * 3.5.4.2 - Array declarators
                    956:  */
                    957: /* dimension can be omitted for first dimension on external */
                    958: extern int INTarray[][3][2][3]; /* links with INTarray on next page */
                    959: 
                    960: static void check_array(iarray)
                    961:        /* first dimension can be left off on formal parameter */
                    962:        int iarray[][3][2][3];
                    963:        {
                    964:        int i, j, k, l, count;
                    965: 
                    966:        /* as initialized below, there are 36 sequential items in the array */
                    967:        for (count=0, i=0; i < 2; ++i)
                    968:                for (j = 0; j < 3; ++j)
                    969:                        for (k = 0; k < 2; ++k)
                    970:                                for (l = 0; l < 3; ++l, ++count)
                    971:                                        iequals(__LINE__, iarray[i][j][k][l], count);
                    972:        }
                    973: 
                    974: static void c3_5_4_2()
                    975:        {
                    976:        double d[2], *dp[2];
                    977: 
                    978:        /* make sure that the first dimension gets handled correctly */
                    979:        check_array(INTarray);
                    980: 
                    981:        /* array of doubles vs. array of pointers to doubles */ 
                    982:        d[0] = 0.0;
                    983:        d[1] = 2.0;
                    984:        dp[0] = d;
                    985:        dp[1] = d+1;
                    986:        dequals(__LINE__, *dp[1], 2.0);
                    987: 
                    988:        /* just to be perverse */
                    989:        *dp[0] = (d[0] && d[1]) ^ (d[0] || d[1]);
                    990:        dequals(__LINE__, d[0], 1.0);
                    991: #if ANSI
                    992:        {
                    993:        void ckarr();
                    994: 
                    995:        ckarr();
                    996:        }
                    997: #endif /* ANSI */
                    998:        } /* end c3_5_4_2 */
                    999: 
                   1000: 
                   1001: 
                   1002: 
                   1003: 
                   1004:                                                                                                                                                                                /* 3.5.4.2 (cont.) */
                   1005: /* array with size is compatible to one lacking size */
                   1006: /* dimension can be omitted for first dimension if initialized */
                   1007: int INTarray[][3][2][3] = 
                   1008:        { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
                   1009:         21,22,23,24,25,26,27,28,29,30,31,32,33,34,35};
                   1010: 
                   1011: #if ANSI
                   1012: int arrfn1();
                   1013: int arrfn1 PARMS((int [][3][2][3]));
                   1014: #if NEW_STYLE_FN_DEF
                   1015: int arrfn1(int a[2][3][2][3])
                   1016: #else
                   1017: int arrfn1(a)
                   1018:        int a[2][3][2][3];
                   1019: #endif /* NEW_STYLE_FN_DEF */
                   1020:        {
                   1021:        return (a[0][0][0][1]);
                   1022:        }
                   1023: void ckarr()
                   1024:        {
                   1025:        int (*parf1)() = arrfn1;
                   1026:        int (*parf2) PARMS((int (*a)[3][2][3])) = &arrfn1;
                   1027: 
                   1028:        iequals(__LINE__, arrfn1(INTarray), 1);
                   1029:        iequals(__LINE__, parf1(INTarray), 1);
                   1030:        iequals(__LINE__, (*parf2)(INTarray), 1);
                   1031:        }
                   1032: #endif /* ANSI */
                   1033: 
                   1034: 
                   1035: 
                   1036: 
                   1037: 
                   1038: 
                   1039: 
                   1040: 
                   1041: 
                   1042: 
                   1043: 
                   1044: 
                   1045: 
                   1046: 
                   1047: 
                   1048: 
                   1049: 
                   1050: 
                   1051: 
                   1052: 
                   1053: 
                   1054: /*
                   1055:  * 3.5.4.3 - Function declarators 
                   1056:  */
                   1057: 
                   1058: /* ANSI rules for compatible function types:
                   1059:        First, convert parameters of type fn or array.
                   1060:        Then, delete any qualifiers on top type of any parameter.
                   1061:        Then, for all cases, return types must be compatible.
                   1062:        Then, one of the following must be true, for compatible fn types:
                   1063: 
                   1064:        1. Both fn types are old-style (no parameter information).
                   1065:        2. If both are prototypes, they agree in number of parms,
                   1066:                  they agree in use of ellipsis, and parms are compatible.
                   1067:        3. If one is prototype and other is old-style declaration (with
                   1068:                  empty parentheses), the prototype must not have ellipsis
                   1069:                  or non-default parm types.
                   1070:        4. Otherwise, one is a prototype and the other is an old-style
                   1071:                  function definition.  The number of parms must agree, and
                   1072:                  each prototype parm must be compatible with the promoted(!)
                   1073:                  definition parm.
                   1074:  */
                   1075: 
                   1076: #if ANSI && HAS_PROTOTYPES
                   1077: int niladic(void) { return 99; }
                   1078: int fn_char(int);
                   1079: int fn_char(); /* ok by rule 3 */
                   1080: int fn_dbl(double);
                   1081: 
                   1082: #if ANSI8703   /* now old-style fn parms are taken as widened before type-matching */
                   1083: int fn_char(c) char c; { return 98; } /* ok by rule 4 */
                   1084: int fn_dbl(f) float f; { return 97; } /* ok by rule 4 */
                   1085: #else
                   1086: int fn_char(c) int c; { return 98; }
                   1087: int fn_dbl(f) double f; { return 97; }
                   1088: #endif /* ANSI8703 */
                   1089: int proto(char, short const int, int, int volatile long, float, double, long double); 
                   1090: 
                   1091: static void c3_5_4_3()
                   1092:        {
                   1093:        int proto(char, const short, int, volatile long, float, double, register long double); /* ok by rule 2 */
                   1094: 
                   1095:        iequals(__LINE__, niladic(), 99);
                   1096:        iequals(__LINE__, fn_char(1), 98);
                   1097:        iequals(__LINE__, fn_dbl(0.), 97);
                   1098:        iequals(__LINE__, proto(1L, 1.0, 1L, '\01', 1, 1, 1), 7);
                   1099: 
                   1100: 
                   1101: 
                   1102: 
                   1103: 
                   1104:                                                                                                                                                                                /* 3.5.4.3 (cont.) */
                   1105: #if ANSI8804
                   1106:        {
                   1107:        int arrfn1();
                   1108:        signed int arrfn1();    /* ok by rule 1 */
                   1109: 
                   1110:        /* ambiguity of typedef vs identifier is always resolved to typedef */
                   1111:        /* so, single typedef name in parentheses is taken as fn of one parm, */
                   1112:        /* not as redundant parentheses on a new identifier */
                   1113:        typedef int I;
                   1114:        int fpfi(int (*)(I));   /* parm is ptr to function of int arg returning int */
                   1115:        iequals(__LINE__, fpfi(fn_char), ivalue(98));
                   1116:        }
                   1117: #endif /* ANSI8804 */
                   1118:        } /* end c3_5_4_3 (ANSI version) */
                   1119: 
                   1120: #if ANSI8804
                   1121: int fpfi(int pfi(int)) { return pfi(0); }
                   1122: #endif
                   1123: 
                   1124: 
                   1125: int arrfn1();
                   1126: signed int arrfn1();   /* ok by rule 1 */
                   1127: 
                   1128: #if NEW_STYLE_FN_DEF
                   1129: int proto(char x1, const short x2, int x3, volatile long x4, float x5, double x6, long double x7)
                   1130: #else
                   1131: int proto(x1, x2, x3, x4, x5, x6, x7)
                   1132:        char x1; const short x2; register int x3; volatile long x4; float x5; double x6; long double x7;
                   1133: #endif /* NEW_STYLE_FN_DEF */
                   1134:        {
                   1135:        return((int)(x1+x2+x3+x4+x5+x6+x7));
                   1136:        }
                   1137: #else  /* if !ANSI || !HAS_PROTOTYPES */
                   1138: static void c3_5_4_3()
                   1139:        {
                   1140:        /* nothing to test, if no prototypes */
                   1141:        }
                   1142: #endif /* ANSI && HAS_PROTOTYPES */
                   1143: 
                   1144: 
                   1145: 
                   1146: 
                   1147: 
                   1148: 
                   1149: 
                   1150: 
                   1151: 
                   1152: 
                   1153: 
                   1154: /*
                   1155:  * 3.5.5 - Type names
                   1156:  */
                   1157: static void c3_5_5()
                   1158:        {
                   1159:        /* these are tested all over, but a few extra ones here ... */
                   1160: 
                   1161: #if ANSI
                   1162:        char *(*(*pfpapc1)(int, ...))[10];
                   1163:        char *(*(*pfpapc2)(char *(*)()))[11] = 0;
                   1164:        iequals(__LINE__, sizeof( char *(*(*)(int, ...))[10]), sizeof pfpapc1);
                   1165:        pfpapc1 = (char *(*(*)(int, ...))[10])pfpapc2;
                   1166: #else
                   1167:        char *(*(*pfpapc1)())[10];
                   1168:        char *(*(*pfpapc2)())[11] = 0;
                   1169:        iequals(__LINE__, sizeof(char *(*(*)())[10]), sizeof pfpapc1);
                   1170:        pfpapc1 = (char *(*(*)())[10])pfpapc2;
                   1171: #endif
                   1172:        checkthat( - __LINE__, pfpapc1 == 0);
                   1173:        }
                   1174: 
                   1175: 
                   1176: 
                   1177: 
                   1178: 
                   1179: 
                   1180: 
                   1181: 
                   1182: 
                   1183: 
                   1184: 
                   1185: 
                   1186: 
                   1187: 
                   1188: 
                   1189: 
                   1190: 
                   1191: 
                   1192: 
                   1193: 
                   1194: 
                   1195: 
                   1196: 
                   1197: 
                   1198: 
                   1199: 
                   1200: 
                   1201: 
                   1202: 
                   1203: 
                   1204: /*
                   1205:  * 3.5.6 - Type definitions 
                   1206:  */
                   1207: static void c3_5_6()
                   1208:        {
                   1209:        /* typedef is not a new type, but rather a synonym. */
                   1210:        struct x 
                   1211:                {
                   1212:                unsigned a:1;
                   1213:                unsigned b:2;
                   1214:                };
                   1215:        typedef struct x X;
                   1216:        X x1;
                   1217:        struct x x2;
                   1218:        unsigned us1;
                   1219:        typedef unsigned US;
                   1220:        US us2;
                   1221: 
                   1222:        x1.a = 2;
                   1223:        x2.a = 2;
                   1224:        iequals(__LINE__, x1.a, 0);
                   1225:        iequals(__LINE__, x2.a, 0);
                   1226:        us1 = us2 = MAX_UINT;
                   1227:        iequals(__LINE__, ++us1, 0);
                   1228:        iequals(__LINE__, ++us2, 0);
                   1229: 
                   1230:        /* ambiguity of typedef vs identifier is always resolved to typedef */
                   1231:        /* In this case, "type spec shall not be omitted" means that if a symbol */
                   1232:        /* could be either a type-name on an un-named field, or an identifier naming a field, */
                   1233:        /* then it must be the former. */
                   1234: #if ANSI8804
                   1235:        {
                   1236:        typedef int I;
                   1237:        struct { const I : 2; int j : 2; } x = {1}; /* "const I" is the type of un-named field */
                   1238: 
                   1239:        iequals(__LINE__, x.j, 1);
                   1240:        }
                   1241: #endif /* ANSI8804 */
                   1242:                
                   1243: 
                   1244: 
                   1245: 
                   1246: 
                   1247: 
                   1248: 
                   1249: 
                   1250: 
                   1251: 
                   1252: 
                   1253: 
                   1254:                                                                                                                                                                                /* 3.5.6 (cont.) */
                   1255: #if ANSI
                   1256:                {
                   1257:                /* typedefs can be nested */
                   1258:                typedef int X;
                   1259:                X a = 0;
                   1260:                iequals(__LINE__, a, 0);
                   1261:                        {
                   1262:                        /* and redefined in other nested contexts */
                   1263:                        X X = 3;
                   1264:                        iequals(__LINE__, X, 3);
                   1265:                        }
                   1266:                /* also, they don't interfere with other name spaces */
                   1267:                        {
                   1268: #if TAG_AND_MEMB_SPACES
                   1269:                        static struct X { int X; } x = {7};
                   1270:                        static struct Y { int Y; } y = {8};
                   1271: #else
                   1272:                        static struct X { int X1; } x = {7};
                   1273:                        static struct Y { int Y1; } y = {8};
                   1274: #endif
                   1275:                        static enum Z { e0, e1, e2 = (X)3 } e;
                   1276:                        struct X *px = (struct X *)&y;
                   1277: 
                   1278:                        e = e2;
                   1279:                        iequals(__LINE__, a, 0);
                   1280:                        iequals(__LINE__, e, 3);
                   1281: #if TAG_AND_MEMB_SPACES
                   1282:                        iequals(__LINE__, x.X, 7);
                   1283:                        iequals(__LINE__, (X) px->X, 8);
                   1284: #else
                   1285:                        iequals(__LINE__, x.X1, 7);
                   1286:                        iequals(__LINE__, (X) px->X1, 8);
                   1287: #endif
                   1288:                        }
                   1289:                }
                   1290: #endif /* ANSI */
                   1291:        } /* end c3_5_6 */
                   1292: 
                   1293: 
                   1294: 
                   1295: 
                   1296: 
                   1297: 
                   1298: 
                   1299: 
                   1300: 
                   1301: 
                   1302: 
                   1303: 
                   1304: /*
                   1305:  * 3.5.7 - Initialization
                   1306:  */
                   1307: static int sarray[5];
                   1308: static struct { int a, b;} st;
                   1309: static struct s1 {int a, b;} s1_init = {3, 4};
                   1310: 
                   1311: struct
                   1312:        {
                   1313:        char *strings[2];
                   1314:        struct
                   1315:                {
                   1316:                int a;
                   1317:                int nums[2][3];
                   1318:                }s;
                   1319:        }x3[] = 
                   1320: /* note that each explicit initializer list can have an extra comma */
                   1321:                {{{"abc", "def", }, {1, {{2,3,4,},{5,6,7,},},},},
                   1322:                {{"ghi", "jkl"}, {9, {{8,7,6},{5,4,3}}}}},
                   1323: #if ANSI       /* very strict about the "Ritchie" rules */
                   1324:        x4[] = {"abc", "def", 1,2,3,4,5,6,7, {"ghi", "jkl", {9, {8,7,6,{5,4,3}}}}};
                   1325:        int a1[2][2][2] = { 0, 1, 2, 3, {4, 5, 6, 7}};
                   1326: #else          /* other compilers, e.g. PCC, vary, so use full braces */
                   1327:        x4[] = {{{"abc", "def", }, {1, {{2,3,4,},{5,6,7,},},},}, {{"ghi", "jkl"}, {9, {{8,7,6},{5,4,3}}}}};
                   1328:        int a1[2][2][2] = { 0, 1, 2, 3, 4, 5, 6, 7};
                   1329: #endif
                   1330:        int a2[2][2][2] = { 0, 1, 2, 3, 4, 5, 6, 7};
                   1331: 
                   1332:        /* special case of a string literal */
                   1333:        char s1[] = "abc";
                   1334:        char s2[] = {'a', 'b', 'c', 0};
                   1335: #if ANSI
                   1336:        char s3[3] = { "def" } ;        /* optional braces */
                   1337: #else
                   1338:        char s3[3] = "de";
                   1339: #endif
                   1340: #if ANSI8712 && WIDE_CHARS
                   1341:        wchar_t s4[] = L"abc";          /* "wide-char" string */
                   1342: #endif
                   1343: 
                   1344:        /* if there are not enough initializers, close off the aggregate with 0 */
                   1345:        int a3[2][2][2] = 
                   1346:                {{{99}}, {{98}}};
                   1347:        struct
                   1348:                {
                   1349:                struct { int a, b;} sm1;
                   1350:                struct { int a, b;} sm2;
                   1351:                } s = 
                   1352:                        {{11},{13}};
                   1353: 
                   1354: 
                   1355:                                                                                                                                                                                /* 3.5.7 (cont.) */
                   1356: #if ANSI
                   1357:        /* unions can be intiialized to their first element */
                   1358:        union
                   1359:                {
                   1360:                double d;
                   1361:                int i;
                   1362:                } u1 = {2.2};
                   1363: #endif
                   1364: 
                   1365: static void c3_5_7()
                   1366:        {
                   1367:        int i = {2};
                   1368:        int j, k, count;
                   1369:        /* auto variables can be initialized to arbitrary expressions */
                   1370:        int a = {1}, b = a*3, c = ivalue(5); /* braces optional on single scalar */
                   1371: 
                   1372: #if ANSI
                   1373:        union
                   1374:                {
                   1375:                double d;
                   1376:                int i;
                   1377:                } u2 = {3.3};
                   1378:        /* aggregates can be initialized */
                   1379:        int aarray[4] = {0, 1, 2, 3};
                   1380:        struct { int a[3], b; } w[] = { {1}, 2 };       /* "inconsistent-braces" example from 3.5.7 */
                   1381: 
                   1382:        for (i = 0; i < 4; ++i)
                   1383:                iequals(__LINE__, aarray[i], i);
                   1384:        iequals(__LINE__, w[0].a[0], 1);
                   1385:        iequals(__LINE__, w[1].a[0], 2);
                   1386:        iequals(__LINE__, w[0].a[1], 0);
                   1387:        iequals(__LINE__, w[1].a[1], 0);
                   1388:        iequals(__LINE__, w[0].b, 0);
                   1389: #endif /* ANSI */
                   1390:        
                   1391: #if ANSI
                   1392:        /* initialize one structure with another */
                   1393:        {
                   1394:        struct s1 x = s1_init;
                   1395:        iequals(__LINE__, x.a, 3);
                   1396:        iequals(__LINE__, x.b, 4);
                   1397:        }
                   1398: #endif
                   1399: 
                   1400: 
                   1401: 
                   1402: 
                   1403: 
                   1404:                                                                                                                                                                                /* 3.5.7 (cont.) */
                   1405:        iequals(__LINE__, a, 1);
                   1406:        iequals(__LINE__, b, 3);
                   1407:        iequals(__LINE__, c, 5);
                   1408: 
                   1409:        /* static items without initializers are initialized to 0 */
                   1410:        for (i = 0; i < 5; ++i)
                   1411:                iequals(__LINE__, sarray[i], 0);
                   1412:        iequals(__LINE__, st.a, 0);
                   1413:        iequals(__LINE__, st.b, 0);
                   1414: 
                   1415:        /* x3 used the explicit form for sub aggregates */
                   1416:        checkthat(__LINE__, 0 == str_cmp(x3[1].strings[1], "jkl"));
                   1417:        iequals(__LINE__, x3[0].s.nums[0][0], 2);
                   1418:        iequals(__LINE__, x3[0].s.nums[1][2], 7);
                   1419:        iequals(__LINE__, x3[1].s.nums[0][0], 8);
                   1420:        iequals(__LINE__, x3[1].s.nums[1][2], 3);
                   1421: 
                   1422:        /* x4 left out some of them , but should look the same */
                   1423:        checkthat(__LINE__, 0 == str_cmp(x4[1].strings[1], "jkl"));
                   1424:        iequals(__LINE__, x4[0].s.nums[0][0], 2);
                   1425:        iequals(__LINE__, x4[0].s.nums[1][2], 7);
                   1426:        iequals(__LINE__, x4[1].s.nums[0][0], 8);
                   1427:        iequals(__LINE__, x4[1].s.nums[1][2], 3);
                   1428: 
                   1429:        /* the two should be identical */
                   1430:        checkthat(__LINE__, sizeof x3 == sizeof x4);
                   1431: 
                   1432:        /* elision of braces */
                   1433:        for (i = 0, count = 0; i < 2; ++i)
                   1434:                for (j = 0; j < 2; ++j)
                   1435:                        for (k = 0; k < 2; ++k, ++count)
                   1436:                                iequals(__LINE__, a1[i][j][k], count);
                   1437:        for (i = 0, count = 0; i < 2; ++i)
                   1438:                for (j = 0; j < 2; ++j)
                   1439:                        for (k = 0; k < 2; ++k, ++count)
                   1440:                                iequals(__LINE__, a2[i][j][k], count);
                   1441: 
                   1442:        /* special forms using string literal initialization */
                   1443:        checkthat(__LINE__, !str_cmp(s1, s2));
                   1444:        iequals(__LINE__, s3[0], 'd');
                   1445:        iequals(__LINE__, s3[1], 'e');
                   1446:        iequals(__LINE__, s3[2], ANSI ? 'f' : '\0');
                   1447: 
                   1448: 
                   1449: 
                   1450: 
                   1451: 
                   1452: 
                   1453: 
                   1454:                                                                                                                                                                                /* 3.5.7 (cont.) */
                   1455:        /* partial intialization fills with 0 */
                   1456:        for (i = 0, count = 0; i < 2; ++i)
                   1457:                for (j = 0; j < 2; ++j)
                   1458:                        for (k = 0; k < 2; ++k, ++count)
                   1459:                                if (count == 0)
                   1460:                                        iequals(__LINE__, a3[i][j][k], 99);
                   1461:                                else if (count == 4)
                   1462:                                        iequals(__LINE__, a3[i][j][k], 98);
                   1463:                                else
                   1464:                                        iequals(__LINE__, a3[i][j][k], 0);
                   1465:        iequals(__LINE__, s.sm1.a, 11);
                   1466:        iequals(__LINE__, s.sm1.b, 0);
                   1467:        iequals(__LINE__, s.sm2.a, 13);
                   1468:        iequals(__LINE__, s.sm2.b, 0);
                   1469: 
                   1470: #if ANSI
                   1471:        /* check union initialization */
                   1472:        dequals(__LINE__, u1.d, 2.2);
                   1473:        dequals(__LINE__, u2.d, 3.3);
                   1474: 
                   1475:        /* auto aggregates are zero-padded */
                   1476:        {
                   1477:                auto int a[10] = {1};
                   1478:                int i;
                   1479: 
                   1480:                for (i = 1; i < 10; ++i)
                   1481:                        iequals(__LINE__, a[i], 0);
                   1482:        }
                   1483:        /* full-expr in initializer is sequence point */
                   1484:        {
                   1485:                int a = ivalue(1), b = a++, c = ++b;
                   1486: 
                   1487:                iequals(__LINE__, a, ivalue(2));
                   1488:                iequals(__LINE__, b, ivalue(2));
                   1489:                iequals(__LINE__, c, ivalue(2));
                   1490:        }
                   1491: 
                   1492: #endif /* ANSI */
                   1493: 
                   1494: 
                   1495: 
                   1496: 
                   1497: 
                   1498: 
                   1499: 
                   1500: 
                   1501: 
                   1502: 
                   1503: 
                   1504:                                                                                                                                                                                /* 3.5.7 (cont.) */
                   1505: #if ANSI8804
                   1506:        /* un-named members are ignored during initialization */
                   1507:        {
                   1508:                struct s1
                   1509:                        {
                   1510:                        unsigned m1:2;
                   1511:                        unsigned :2;
                   1512:                        unsigned m2:2;
                   1513:                        unsigned m3:2;
                   1514:                        } s1 = { 1, 2 };
                   1515:                iequals(__LINE__, s1.m1, 1);
                   1516:                iequals(__LINE__, s1.m2, 2);
                   1517:                iequals(__LINE__, s1.m3, 0);
                   1518:        }
                   1519: #endif /* ANSI8804 */
                   1520: 
                   1521:        } /* end c3_5_7 */
                   1522: 
                   1523: #else /* if SKIP35 */
                   1524: void c3_5() { pr_skip("c3_5: SKIPPED ENTIRELY\n"); }
                   1525: #endif /* SKIP35 */
                   1526: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.