Ignore:
Timestamp:
Mar 9, 2024, 5:40:09 PM (2 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
b64d0f4
Parents:
03606ce
Message:

switch to tabs, first attempt changing program-input style

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/mike_brooks_MMath/programs/bkgd-carray-arrty.c

    r03606ce r266732e  
    2424
    2525
    26     // SHOW(sizeof( a   ), "%zd");
    27     // SHOW(sizeof(&a   ), "%zd");
    28     // SHOW(sizeof( a[0]), "%zd");
    29     // SHOW(sizeof(&a[0]), "%zd");
     26        // SHOW(sizeof( a   ), "%zd");
     27        // SHOW(sizeof(&a   ), "%zd");
     28        // SHOW(sizeof( a[0]), "%zd");
     29        // SHOW(sizeof(&a[0]), "%zd");
    3030
    3131
    3232
    3333int main() {
     34        float a[10];
     35        static_assert(sizeof(float) == 4);              $\C{// floats (array elements) are 4 bytes}$
     36        static_assert(sizeof(void*) == 8);              $\C{// pointers are 8 bytes}$
     37        static_assert(sizeof(a) == 40);                 $\C{// array}$
     38        static_assert(sizeof(&a) == 8 );                $\C{// pointer to array}$
     39        static_assert(sizeof(a[0]) == 4 );              $\C{// first element}$
     40        static_assert(sizeof(&(a[0])) == 8 );   $\C{// pointer to first element}$
    3441
    35 /*
    36 When a programmer works with an array, C semantics provide access to a type that is different in every way from ``pointer to its first element.''
     42        typeof(&a) x;                                                   $\C{// x is pointer to array}$
     43        typeof(&(a[0])) y;                                              $\C{// y is pointer to first element}$
     44        @x = y;@                                                                $\C{// ill-typed}$
     45        @y = x;@                                                                $\C{// ill-typed}$
     46        static_assert(sizeof(typeof(a)) == 40);
     47        static_assert(sizeof(typeof(&a)) == 8 );
     48        static_assert(sizeof(typeof(a[0])) == 4 );
     49        static_assert(sizeof(typeof(&(a[0]))) == 8 );
    3750
    38 Its qualities become apparent by inspecting the declaration
    39 */
    40     float a[10];
    41 /*
     51        void f( float (*pa)[10] ) {
     52            static_assert(sizeof(   *pa     ) == 40); $\C{// array}$
     53            static_assert(sizeof(    pa     ) == 8 ); $\C{// pointer to array}$
     54            static_assert(sizeof(  (*pa)[0] ) == 4 ); $\C{// first element}$
     55            static_assert(sizeof(&((*pa)[0])) == 8 ); $\C{// pointer to first element}$
     56        }
     57        f( & a );
    4258
    43 The inspection begins by using @sizeof@ to provide definite program semantics for the intuition of an expression's type.
     59        float fs[] = {3.14, 1.707};
     60        char cs[] = "hello";
    4461
    45 Assuming a target platform keeps things concrete:
    46 */
    47     static_assert(sizeof(float)==4);    // floats (array elements) are 4 bytes
    48     static_assert(sizeof(void*)==8);    // pointers are 8 bytes
    49 /*
    50 
    51 Consider the sizes of expressions derived from @a@, modified by adding ``pointer to'' and ``first element'' (and including unnecessary parentheses to avoid confusion about precedence).
    52 */
    53     static_assert(sizeof(  a    ) == 40); // array
    54     static_assert(sizeof(& a    ) == 8 ); // pointer to array
    55     static_assert(sizeof(  a[0] ) == 4 ); // first element
    56     static_assert(sizeof(&(a[0])) == 8 ); // pointer to first element
    57 /*
    58 That @a@ takes up 40 bytes is common reasoning for C programmers.
    59 Set aside for a moment the claim that this first assertion is giving information about a type.
    60 For now, note that an array and a pointer to its first element are, sometimes, different things.
    61 
    62 The idea that there is such a thing as a pointer to an array may be surprising.
    63 It is not the same thing as a pointer to the first element:
    64 */
    65     typeof(& a    ) x;   // x is pointer to array
    66     typeof(&(a[0])) y;   // y is pointer to first element
    67                        ERR(
    68     x = y;             // ill-typed
    69     y = x;             // ill-typed
    70                        )
    71 /*
    72 The first gets
    73     warning: warning: assignment to `float (*)[10]' from incompatible pointer type `float *'
    74 and the second gets the opposite.
    75 */
    76 
    77 /*
    78 We now refute a concern that @sizeof(a)@ is reporting on special knowledge from @a@ being an local variable,
    79 say that it is informing about an allocation, rather than simply a type.
    80 
    81 First, recognizing that @sizeof@ has two forms, one operating on an expression, the other on a type, we observe that the original answers are unaffected by using the type-parameterized form:
    82 */
    83     static_assert(sizeof(typeof(  a    )) == 40);
    84     static_assert(sizeof(typeof(& a    )) == 8 );
    85     static_assert(sizeof(typeof(  a[0] )) == 4 );
    86     static_assert(sizeof(typeof(&(a[0]))) == 8 );
    87 
    88 /*
    89 Finally, the same sizing is reported when there is no allocation at all, and we launch the analysis instead from the pointer-to-array type.
    90 */
    91     void f( float (*pa)[10] ) {
    92         static_assert(sizeof(   *pa     ) == 40); // array
    93         static_assert(sizeof(    pa     ) == 8 ); // pointer to array
    94         static_assert(sizeof(  (*pa)[0] ) == 4 ); // first element
    95         static_assert(sizeof(&((*pa)[0])) == 8 ); // pointer to first element
    96     }
    97     f( & a );
    98 
    99 /*
    100 So, in spite of considerable programmer success enabled by an understanding that
    101 an array just a pointer to its first element (revisited TODO pointer decay),
    102 this understanding is simplistic.
    103 */
    104 
    105 /*
    106 A shortened form for declaring local variables exists, provided that length information is given in the initializer:
    107 */
    108     float fs[] = {3.14, 1.707};
    109     char cs[] = "hello";
    110 
    111     static_assert( sizeof(fs) == 2 * sizeof(float) );
    112     static_assert( sizeof(cs) == 6 * sizeof(char) );  // 5 letters + 1 null terminator
    113 
    114 /*
    115 In these declarations, the resulting types are both arrays, but their lengths are inferred.
    116 */
    117 
     62        static_assert( sizeof(fs) == 2 * sizeof(float) );
     63        static_assert( sizeof(cs) == 6 * sizeof(char) );  $\C{// 5 letters + 1 null terminator}$
    11864}
    11965
     66void syntaxReferenceCheck(void) {
     67        // $\rightarrow$ & (base element)
     68        //     & @float@
     69        //     & @float x;@
     70        //     & @[ float ]@
     71        //     & @[ float ]@
     72        float x0;
    12073
    121 void syntaxReferenceCheck(void) {
    122     // $\rightarrow$ & (base element)
    123     //     & @float@
    124     //     & @float x;@
    125     //     & @[ float ]@
    126     //     & @[ float ]@
    127     float x0;
     74        // $\rightarrow$ & pointer
     75        //     & @float *@
     76        //     & @float * x;@
     77        //     & @[ * float ]@
     78        //     & @[ * float ]@
     79        float * x1;
    12880
    129     // $\rightarrow$ & pointer
    130     //     & @float *@
    131     //     & @float * x;@
    132     //     & @[ * float ]@
    133     //     & @[ * float ]@
    134     float * x1;
     81        // $\rightarrow$ & array
     82        //     & @float[10]@
     83        //     & @float x[10];@
     84        //     & @[ [10] float ]@
     85        //     & @[ array(float, 10) ]@
     86        float x2[10];
    13587
    136     // $\rightarrow$ & array
    137     //     & @float[10]@
    138     //     & @float x[10];@
    139     //     & @[ [10] float ]@
    140     //     & @[ array(float, 10) ]@
    141     float x2[10];
     88        typeof(float[10]) x2b;
    14289
    143     typeof(float[10]) x2b;
    144 
    145     // & array of pointers
    146     //     & @(float*)[10]@
    147     //     & @float *x[10];@
    148     //     & @[ [10] * float ]@
    149     //     & @[ array(*float, 10) ]@
    150     float *x3[10];
     90        // & array of pointers
     91        //     & @(float*)[10]@
     92        //     & @float *x[10];@
     93        //     & @[ [10] * float ]@
     94        //     & @[ array(*float, 10) ]@
     95        float *x3[10];
    15196//    (float *)x3a[10];  NO
    15297
    153     // $\rightarrow$ & pointer to array
    154     //     & @float(*)[10]@
    155     //     & @float (*x)[10];@
    156     //     & @[ * [10] float ]@
    157     //     & @[ * array(float, 10) ]@
    158     float (*x4)[10];
     98        // $\rightarrow$ & pointer to array
     99        //     & @float(*)[10]@
     100        //     & @float (*x)[10];@
     101        //     & @[ * [10] float ]@
     102        //     & @[ * array(float, 10) ]@
     103        float (*x4)[10];
    159104
    160     // & pointer to array
    161     //     & @(float*)(*)[10]@
    162     //     & @float *(*x)[10];@
    163     //     & @[ * [10] * float ]@
    164     //     & @[ * array(*float, 10) ]@
    165     float *(*x5)[10];
    166     x5 =     (float*(*)[10]) x4;
     105        // & pointer to array
     106        //     & @(float*)(*)[10]@
     107        //     & @float *(*x)[10];@
     108        //     & @[ * [10] * float ]@
     109        //     & @[ * array(*float, 10) ]@
     110        float *(*x5)[10];
     111        x5 =     (float*(*)[10]) x4;
    167112//    x5 =     (float(*)[10]) x4;  // wrong target type; meta test suggesting above cast uses correct type
    168113
    169     // [here]
    170     // const
     114        // [here]
     115        // const
    171116
    172     // [later]
    173     // static
    174     // star as dimension
    175     // under pointer decay:                int p1[const 3]  being  int const *p1
     117        // [later]
     118        // static
     119        // star as dimension
     120        // under pointer decay:                int p1[const 3]  being  int const *p1
    176121
    177     const float * y1;
    178     float const * y2;
    179     float * const y3;
     122        const float * y1;
     123        float const * y2;
     124        float * const y3;
    180125
    181     y1 = 0;
    182     y2 = 0;
    183     // y3 = 0; // bad
     126        y1 = 0;
     127        y2 = 0;
     128        // y3 = 0; // bad
    184129
    185     // *y1 = 3.14; // bad
    186     // *y2 = 3.14; // bad
    187     *y3 = 3.14;
     130        // *y1 = 3.14; // bad
     131        // *y2 = 3.14; // bad
     132        *y3 = 3.14;
    188133
    189     const float z1 = 1.414;
    190     float const z2 = 1.414;
     134        const float z1 = 1.414;
     135        float const z2 = 1.414;
    191136
    192     // z1 = 3.14; // bad
    193     // z2 = 3.14; // bad
     137        // z1 = 3.14; // bad
     138        // z2 = 3.14; // bad
    194139
    195140
     
    199144void stx2() { const T x[10];
    200145//            x[5] = 3.14; // bad
    201             }
     146                }
    202147void stx3() { T const x[10];
    203148//            x[5] = 3.14; // bad
    204             }
     149                }
     150
     151// Local Variables: //
     152// compile-command: "sed -f sedcmd bkgd-carray-arrty.c > tmp.c; gcc tmp.c" //
     153// End: //
Note: See TracChangeset for help on using the changeset viewer.