// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // designations.c -- // // Author : Rob Schluntz // Created On : Thu Jun 29 15:26:36 2017 // Last Modified By : Peter A. Buhr // Last Modified On : Tue Jan 28 21:49:50 2025 // Update Count : 82 // // Note: this test case has been crafted so that it compiles with both cfa and with gcc without any modifications. #include #ifdef __cforall #define AT @ #else #define AT #endif #pragma GCC diagnostic ignored "-Wmissing-braces" #pragma GCC diagnostic ignored "-Woverride-init" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" const int indentAmt = 2; void indent( int level ) { printf( "%*s", level, "" ); } // A contains fields with different types (int vs. int *) struct A { int x, y; int * ptr; }; void printA( struct A a, int level ) { indent( level ); printf( "(A){ %d %d %p }\n", a.x, a.y, a.ptr ); } // B contains struct members struct B { struct A a0, a1; }; void printB( struct B b, int level ) { indent( level ); printf( "(B){\n" ); printA( b.a0, level+indentAmt ); printA( b.a1, level+indentAmt ); indent( level ); printf( "}\n" ); } // C contains an array - tests that after 3 ints, the members of B are initialized. struct C { int arr[3]; struct B b; }; void printC( struct C c, int level ) { indent( level ); printf( "(C){\n" ); indent( level+indentAmt ); printf( "(int[]{ %d %d %d }\n", c.arr[0], c.arr[1], c.arr[2] ); printB( c.b, level+indentAmt ); indent( level ); printf( "}\n" ); } // D contains an unnamed aggregate - tests that this doesn't interfere with initialization. struct D { struct { int x; }; }; void printD( struct D d, int level ) { indent( level); printf( "(D){ %d }\n", d.x ); } // E tests unions union E { struct A a; struct B b; struct C c; struct D d; int i; }; struct Fred { double i[3]; int j; struct Mary { struct Jane { double j; } j; double i; } m; }; struct Fred s1 AT= { .m.j = { 3 } }; struct Fred s2 AT= { .i = { [2] = 2 } }; int main() { // simple designation case - starting from beginning of structure, leaves ptr default-initialized (zero) struct A y0 = { .x = 2, .y = 3 }; // simple initializaiton case - initialize all elements explicitly with no designations struct A y1 = { 2, 3, 0 }; // use designation to move to member y, leaving x default-initialized (zero) struct A y2 = { .y = 3, 0 }; #if ERROR struct A yErr0 = { {} // error - empty scalar initializer is illegal }; #endif printf( "=====A=====\n" ); printA( y0, 0 ); printA( y1, 0 ); printA( y2, 0 ); printf( "=====A=====\n\n" ); // initialize only first element (z0.a.x), leaving everything else default-initialized (zero), no nested curly-braces struct B z0 = { 5 }; // some nested curly braces, use designation to 'jump around' within structure, leaving some members default-initialized struct B z1 = { { 3 }, // z1.a0 { 4 }, // z1.a1 .a0 = { 5 }, // z1.a0 { 6 }, // z1.a1 .a0.y = 2, // z1.a0.y 0, // z1.a0.ptr }; // z2.a0.y and z2.a0.ptr default-initialized, everything else explicit struct B z2 = { { 1 }, { 2, 3, 0 } }; // initialize every member, omitting nested curly braces struct B z3 = { 1, 2, 0, 4, 5, 0 }; // no initializer - legal C, but garbage values - don't print this one struct B z4; // Mark this as unused since it can't be printed. (void)z4; // no curly braces - initialize with object of same type struct B z5 = z2; // z6.a0.y and z6.a0.ptr default-initialized, everything else explicit. // no curly braces on z6.a1 initializers struct B z6 = { { 1 }, 2, 3, 0 }; printf( "=====B=====\n" ); printB( z0, 0 ); printB( z1, 0 ); printB( z2, 0 ); printB( z3, 0 ); printB( z5, 0 ); printB( z6, 0 ); printf( "=====B=====\n\n" ); // TODO: what about extra things in a nested init? are empty structs skipped?? // test that initializing 'past array bound' correctly moves to next member. struct C c1 = { 2, 3, 4, // arr 5, 6, 0, // b.a0 7, 8, 0, // b.a1 }; printf( "=====C=====\n" ); printC( c1, 0 ); printf( "=====C=====\n\n" ); #if ERROR // nested initializer can't refer to same type in C struct C cErr0 = { c1 }; // must use curly braces to initialize members struct C cErr1 = 2; // can't initialize with array compound literal struct C cErr2 = { (int[3]) { 1, 2, 3 } // error: array initialized from non-constant array expression }; #endif #if WARNING // can't initialize array with array - converts to int* int cWarn0_arr[3] = { 1, 2, 3 }; struct C cWarn0 = { cWarn0_arr // warning: initialization makes integer from ptr without cast }; #endif // array designation int i[2] = { [1] = 3 }; // allowed to have 'too many' initialized lists - essentially they are ignored. int i1 = { 3 }; printf( "====ARR====\n" ); printf( "[%d, %d]\n", i[0], i[1] ); printf( "%d\n", i1 ); printf( "====ARR====\n\n" ); // doesn't work yet. // designate unnamed object's members // struct D d = { .x = 3 }; #if ERROR struct D d1 = { .y = 3 }; #endif // simple union initialization - initialized first member (e0.a) union E e0 = { y0 }; // simple union initialization - initializes first member (e1.a) - with nested initializer list union E e1 = { { 2, 3, 0 } }; // simple union initialization - initializes first member (e2.a) - without nested initializer list union E e2 = { 2, 3, 0 }; // move cursor to e4.b.a0.x and initialize until e3.b.a1.ptr inclusive union E e3 = { .b.a0.x = 2, 3, 0, 5, 6, 0 }; printf( "=====E=====\n" ); printA( e0.a, 0 ); printA( e1.a, 0 ); printA( e2.a, 0 ); printB( e3.b, 0 ); printf( "=====E=====\n\n" ); // special case of initialization: char[] can be initialized with a string literal const char * str0 = "hello"; char str1[] = "hello"; const char c2[] = "abc"; const char c3[] = { 'a', 'b', 'c' }; const char c4[][2] = { { 'a', 'b' }, { 'c', 'd' }, { 'c', 'd' } }; const char ch = c4[0][0]; printf( "==STRINGS==\n" ); printf( "%s\n", str0 ); printf( "%s\n", str1 ); printf( "%s\n", c2 ); printf( "[%c, %c, %c]\n", c3[0], c3[1], c3[2] ); for ( unsigned index = 0 ; index < 3 ; ++index ) { printf( "[%c, %c]\n", c4[index][0], c4[index][1] ); } printf( "%c\n", ch ); printf( "==STRINGS==\n\n" ); // more cases // int widths[] = { [3 ... 9] = 1, [10 ... 99] = 2, [100] = 3 }; // int widths[] = { [3 ~ 9] = 1, [10 ~ 99] = 2, [100] = 3 }; struct point { int x, y; }; struct point p = { .y = 5, .x = 7 }; union foo { int i; double d; }; union foo f = { .d = 4 }; int v1 = 1, v2 = 2, v4 = 4; int w[6] = { [1] = v1, v2, [4] = v4 }; int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\v'] = 1, ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 }; struct point ptarray[10] = { [2].y = 34, [2].x = 35, [0].x = 36 }; printf( "===EXTRA===\n" ); printf( "(point){ %d %d }\n", p.x, p.y ); printf( "(foo){ %f }\n", f.d ); printf( "[%d, %d, %d, %d, %d, %d]\n", w[0], w[1], w[2], w[3], w[4], w[5] ); printf( "[%d ... %d ...]\n", whitespace[0], whitespace[32] ); printf( "[{ %d %d }, { %d %d }, { %d %d } ...]\n", ptarray[0].x, ptarray[0].y, ptarray[1].x, ptarray[1].y, ptarray[2].x, ptarray[2].y ); printf( "===EXTRA===\n\n" ); } // Local Variables: // // tab-width: 4 // // End: //