|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.