#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 ar[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(ar) == 40 ); $\C{// array}$ static_assert( sizeof(&ar) == 8 ); $\C{// pointer to array}$ static_assert( sizeof(ar[0]) == 4 ); $\C{// first element}$ static_assert( sizeof(&(ar[0])) == 8 ); $\C{// pointer to first element}$ typeof(&ar) x = &ar; $\C{// x is pointer to array}$ typeof(&(ar[0])) y = &ar[0]; $\C{// y is pointer to first element}$ @x = y;@ $\C{// ill-typed}$ @y = x;@ $\C{// ill-typed}$ static_assert( sizeof(typeof(ar)) == 40 ); $\C{// array}$ static_assert( sizeof(typeof(&ar)) == 8 ); $\C{// pointer to array}$ static_assert( sizeof(typeof(ar[0])) == 4 ); $\C{// first element}$ static_assert( sizeof(typeof(&(ar[0]))) == 8 ); $\C{// pointer to first element}$ 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( &ar ); float fs@[]@ = {3.14, 1.77}; char cs@[]@ = "hello"; // shorthand for { 'h', 'e', 'l', 'l', 'o', '\0' } static_assert( sizeof(fs) == 2 * sizeof(float) ); static_assert( sizeof(cs) == 6 * sizeof(char) ); $\C{// 5 letters + 1 null terminator}$ float fm[]@[2]@ = { {3.14, 1.77}, {12.4, 0.01}, {7.8, 1.23} }; $\C{// brackets define structuring}$ char cm[]@[sizeof("hello")]@ = { "hello", "hello", "hello" }; static_assert( sizeof(fm) == 3 * 2 * sizeof(float) ); static_assert( sizeof(cm) == 3 * 6 * sizeof(char) ); } 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-11 -Wall -Wextra -x c -" // // End: //