#include #include #include #define SHOW(x, fmt) printf( #x ": " fmt "\n", x ) #ifdef ERRS #define ERR(...) __VA_ARGS__ #else #define ERR(...) #endif // int main( int argc, const char *argv[] ) { // assert(argc == 2); // const int n = atoi(argv[1]); // assert(0 < n && n < 1000); // float a1[42]; // float a2[n]; // SHOW(sizeof(a1), "%zd"); // SHOW(sizeof(a2), "%zd"); // } // SHOW(sizeof( a ), "%zd"); // SHOW(sizeof(&a ), "%zd"); // SHOW(sizeof( a[0]), "%zd"); // SHOW(sizeof(&a[0]), "%zd"); int main() { float a[10]; static_assert(sizeof(float) == 4); $\C{// floats (array elements) are 4 bytes}$ static_assert(sizeof(void*) == 8); $\C{// pointers are 8 bytes}$ static_assert(sizeof(a) == 40); $\C{// array}$ static_assert(sizeof(&a) == 8 ); $\C{// pointer to array}$ static_assert(sizeof(a[0]) == 4 ); $\C{// first element}$ static_assert(sizeof(&(a[0])) == 8 ); $\C{// pointer to first element}$ typeof(&a) x; $\C{// x is pointer to array}$ typeof(&(a[0])) y; $\C{// y is pointer to first element}$ @x = y;@ $\C{// ill-typed}$ @y = x;@ $\C{// ill-typed}$ static_assert(sizeof(typeof(a)) == 40); static_assert(sizeof(typeof(&a)) == 8 ); static_assert(sizeof(typeof(a[0])) == 4 ); static_assert(sizeof(typeof(&(a[0]))) == 8 ); void f( float (*pa)[10] ) { static_assert(sizeof( *pa ) == 40); $\C{// array}$ static_assert(sizeof( pa ) == 8 ); $\C{// pointer to array}$ static_assert(sizeof( (*pa)[0] ) == 4 ); $\C{// first element}$ static_assert(sizeof(&((*pa)[0])) == 8 ); $\C{// pointer to first element}$ } f( & a ); float fs[] = {3.14, 1.707}; char cs[] = "hello"; static_assert( sizeof(fs) == 2 * sizeof(float) ); static_assert( sizeof(cs) == 6 * sizeof(char) ); $\C{// 5 letters + 1 null terminator}$ } void syntaxReferenceCheck(void) { // $\rightarrow$ & (base element) // & @float@ // & @float x;@ // & @[ float ]@ // & @[ float ]@ float x0; // $\rightarrow$ & pointer // & @float *@ // & @float * x;@ // & @[ * float ]@ // & @[ * float ]@ float * x1; // $\rightarrow$ & array // & @float[10]@ // & @float x[10];@ // & @[ [10] float ]@ // & @[ array(float, 10) ]@ float x2[10]; typeof(float[10]) x2b; // & array of pointers // & @(float*)[10]@ // & @float *x[10];@ // & @[ [10] * float ]@ // & @[ array(*float, 10) ]@ float *x3[10]; // (float *)x3a[10]; NO // $\rightarrow$ & pointer to array // & @float(*)[10]@ // & @float (*x)[10];@ // & @[ * [10] float ]@ // & @[ * array(float, 10) ]@ float (*x4)[10]; // & pointer to array // & @(float*)(*)[10]@ // & @float *(*x)[10];@ // & @[ * [10] * float ]@ // & @[ * array(*float, 10) ]@ float *(*x5)[10]; x5 = (float*(*)[10]) x4; // x5 = (float(*)[10]) x4; // wrong target type; meta test suggesting above cast uses correct type // [here] // const // [later] // static // star as dimension // under pointer decay: int p1[const 3] being int const *p1 const float * y1; float const * y2; float * const y3; y1 = 0; y2 = 0; // y3 = 0; // bad // *y1 = 3.14; // bad // *y2 = 3.14; // bad *y3 = 3.14; const float z1 = 1.414; float const z2 = 1.414; // z1 = 3.14; // bad // z2 = 3.14; // bad } #define T float void stx2() { const T x[10]; // x[5] = 3.14; // bad } void stx3() { T const x[10]; // x[5] = 3.14; // bad } // Local Variables: // // compile-command: "sed -f sedcmd bkgd-carray-arrty.c | gcc -c -x c -" // // End: //