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/background.tex

    r03606ce r266732e  
    2121This behaviour is typically one of
    2222\begin{itemize}
    23     \item my statement that the compiler accepts or rejects the program
    24     \item the program's printed output, which I show
    25     \item my implied assurance that its assertions do not fail when run
     23        \item my statement that the compiler accepts or rejects the program
     24        \item the program's printed output, which I show
     25        \item my implied assurance that its assertions do not fail when run
    2626\end{itemize}
    2727
    2828The compiler whose program semantics is shown is
    29 \begin{lstlisting}
     29\begin{cfa}
    3030$ gcc --version
    3131gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
    32 \end{lstlisting}
     32\end{cfa}
    3333running on Architecture @x86_64@, with the same environment targeted.
    3434
     
    3939\subsection{C reports many ill-typed expressions as warnings}
    4040
    41 TODO: typeset
    42 \lstinputlisting[language=C, firstline=13, lastline=56]{bkgd-c-tyerr.c}
     41These attempts to assign @y@ to @x@ and vice-versa are obviously ill-typed.
     42\lstinput{12-15}{bkgd-c-tyerr.c}
     43with warnings:
     44\begin{cfa}
     45warning: assignment to 'float *' from incompatible pointer type 'void (*)(void)'
     46warning: assignment to 'void (*)(void)' from incompatible pointer type 'float *'
     47\end{cfa}
     48Similarly,
     49\lstinput{17-19}{bkgd-c-tyerr.c}
     50with warning:
     51\begin{cfa}
     52warning: passing argument 1 of 'f' from incompatible pointer type
     53note: expected 'void (*)(void)' but argument is of type 'float *'
     54\end{cfa}
     55with a segmentation fault at runtime.
     56
     57That @f@'s attempt to call @g@ fails is not due to 3.14 being a particularly unlucky choice of value to put in the variable @pi@.
     58Rather, it is because obtaining a program that includes this essential fragment, yet exhibits a behaviour other than "doomed to crash," is a matter for an obfuscated coding competition.
     59
     60A "tractable syntactic method for proving the absence of certain program behaviours by classifying phrases according to the kinds of values they compute"*1 rejected the program.
     61The behaviour (whose absence is unprovable) is neither minor nor unlikely.
     62The rejection shows that the program is ill-typed.
     63
     64Yet, the rejection presents as a GCC warning.
     65
     66In the discussion following, ``ill-typed'' means giving a nonzero @gcc -Werror@ exit condition with a message that discusses typing.
     67
     68*1  TAPL-pg1 definition of a type system
    4369
    4470
     
    4773\subsection{C has an array type (!)}
    4874
    49 TODO: typeset
    50 \lstinputlisting[language=C, firstline=35, lastline=116]{bkgd-carray-arrty.c}
     75When 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.''
     76Its qualities become apparent by inspecting the declaration
     77\lstinput{34-34}{bkgd-carray-arrty.c}
     78The inspection begins by using @sizeof@ to provide definite program semantics for the intuition of an expression's type.
     79Assuming a target platform keeps things concrete:
     80\lstinput{35-36}{bkgd-carray-arrty.c}
     81Consider the sizes of expressions derived from @a@, modified by adding ``pointer to'' and ``first element'' (and including unnecessary parentheses to avoid confusion about precedence).
     82\lstinput{37-40}{bkgd-carray-arrty.c}
     83That @a@ takes up 40 bytes is common reasoning for C programmers.
     84Set aside for a moment the claim that this first assertion is giving information about a type.
     85For now, note that an array and a pointer to its first element are, sometimes, different things.
     86
     87The idea that there is such a thing as a pointer to an array may be surprising.
     88It is not the same thing as a pointer to the first element:
     89\lstinput{42-45}{bkgd-carray-arrty.c}
     90The first gets
     91\begin{cfa}
     92warning: assignment to `float (*)[10]' from incompatible pointer type `float *'
     93\end{cfa}
     94and the second gets the opposite.
     95
     96We now refute a concern that @sizeof(a)@ is reporting on special knowledge from @a@ being an local variable,
     97say that it is informing about an allocation, rather than simply a type.
     98
     99First, 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:
     100\lstinput{46-50}{bkgd-carray-arrty.c}
     101Finally, the same sizing is reported when there is no allocation at all, and we launch the analysis instead from the pointer-to-array type.
     102\lstinput{51-57}{bkgd-carray-arrty.c}
     103So, in spite of considerable programmer success enabled by an understanding that an array just a pointer to its first element (revisited TODO pointer decay), this understanding is simplistic.
     104
     105A shortened form for declaring local variables exists, provided that length information is given in the initializer:
     106\lstinput{59-63}{bkgd-carray-arrty.c}
     107In these declarations, the resulting types are both arrays, but their lengths are inferred.
     108
     109\begin{tabular}{lllllll}
     110@float x;@ & $\rightarrow$ & (base element) & @float@ & @float x;@ & @[ float ]@ & @[ float ]@ \\
     111@float * x;@ & $\rightarrow$ & pointer & @float *@ & @float * x;@ & @[ * float ]@ & @[ * float ]@ \\
     112@float x[10];@ & $\rightarrow$ & array & @float[10]@ & @float x[10];@ & @[ [10] float ]@ & @[ array(float, 10) ]@ \\
     113@float *x[10];@ & $\rightarrow$ & array of pointers & @(float*)[10]@ & @float *x[10];@ & @[ [10] * float ]@ & @[ array(*float, 10) ]@ \\
     114@float (*x)[10];@ & $\rightarrow$ & pointer to array & @float(*)[10]@ & @float (*x)[10];@ & @[ * [10] float ]@ & @[ * array(float, 10) ]@ \\
     115@float *(*x5)[10];@ & $\rightarrow$ & pointer to array & @(float*)(*)[10]@ & @float *(*x)[10];@ & @[ * [10] * float ]@ & @[ * array(*float, 10) ]@
     116\end{tabular}
     117\begin{cfa}
     118         x5 =    (float*(*)[10]) x4;
     119//      x5 =     (float(*)[10]) x4;  // wrong target type; meta test suggesting above cast uses correct type
     120
     121        // [here]
     122        // const
     123
     124        // [later]
     125        // static
     126        // star as dimension
     127        // under pointer decay:                         int p1[const 3]  being  int const *p1
     128
     129        const float * y1;
     130        float const * y2;
     131        float * const y3;
     132
     133        y1 = 0;
     134        y2 = 0;
     135        // y3 = 0; // bad
     136
     137        // *y1 = 3.14; // bad
     138        // *y2 = 3.14; // bad
     139        *y3 = 3.14;
     140
     141        const float z1 = 1.414;
     142        float const z2 = 1.414;
     143
     144        // z1 = 3.14; // bad
     145        // z2 = 3.14; // bad
     146
     147
     148}
     149
     150#define T float
     151void stx2() { const T x[10];
     152//                      x[5] = 3.14; // bad
     153                        }
     154void stx3() { T const x[10];
     155//                      x[5] = 3.14; // bad
     156                        }
     157\end{cfa}
    51158
    52159My contribution is enabled by recognizing
    53160\begin{itemize}
    54     \item There is value in using a type that knows how big the whole thing is.
    55     \item The type pointer to (first) element does not.
    56     \item C \emph{has} a type that knows the whole picture: array, e.g. @T[10]@.
    57     \item This type has all the usual derived forms, which also know the whole picture.  A usefully noteworthy example is pointer to array, e.g. @T(*)[10]@.
     161        \item There is value in using a type that knows how big the whole thing is.
     162        \item The type pointer to (first) element does not.
     163        \item C \emph{has} a type that knows the whole picture: array, e.g. @T[10]@.
     164        \item This type has all the usual derived forms, which also know the whole picture.  A usefully noteworthy example is pointer to array, e.g. @T(*)[10]@.
    58165\end{itemize}
    59166
     
    75182a declaration is always the type followed by the declared identifier name;
    76183for the example of letting @x@ be a \emph{pointer to array}, the declaration is spelled:
    77 \begin{lstlisting}
     184\begin{cfa}
    78185[ * [10] T ] x;
    79 \end{lstlisting}
     186\end{cfa}
    80187The \CFA-Full column gives the spelling of a different type, introduced in TODO, which has all of my contributed improvements for safety and ergonomics.
    81188
     
    83190\textbf{Unfortunate Syntactic Reference}
    84191
    85 \noindent
     192\begin{figure}
     193\centering
     194\setlength{\tabcolsep}{3pt}
    86195\begin{tabular}{llllll}
    87     & Description & Type & Declaration & \CFA-C  & \CFA-Full \\ \hline
    88     $\triangleright$ & val.
    89         & @T@
    90         & @T x;@
    91         & @[ T ]@
    92         &
    93         \\ \hline
    94     & \pbox{20cm}{ \vspace{2pt} val.\\ \footnotesize{no writing the val.\ in \lstinline{x}}   }\vspace{2pt}
    95         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T} \\ \lstinline{T const}   }
    96         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T x;} \\ \lstinline{T const x;}   }
    97         & @[ const T ]@
    98         &
    99         \\ \hline
    100     $\triangleright$ & ptr.\ to val.
    101         & @T *@
    102         & @T * x;@
    103         & @[ * T ]@
    104         &
    105         \\ \hline
    106     & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}}   }\vspace{2pt}
    107         & @T * const@
    108         & @T * const x;@
    109         & @[ const * T ]@
    110         &
    111         \\ \hline
    112     & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*x}}   }\vspace{2pt}
    113         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T *} \\ \lstinline{T const *}   }
    114         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x;} \\ \lstinline{T const * x;}   }
    115         & @[ * const T ]@
    116         &
    117         \\ \hline
    118     $\triangleright$ & ar.\ of val.
    119         & @T[10]@
    120         & @T x[10];@
    121         & @[ [10] T ]@
    122         & @[ array(T, 10) ]@
    123         \\ \hline
    124     & \pbox{20cm}{ \vspace{2pt} ar.\ of val.\\ \footnotesize{no writing the val.\ in \lstinline{x[5]}}   }\vspace{2pt}
    125         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T[10]} \\ \lstinline{T const[10]}   }
    126         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T x[10];} \\ \lstinline{T const x[10];}   }
    127         & @[ [10] const T ]@
    128         & @[ const array(T, 10) ]@
    129         \\ \hline
    130     & ar.\ of ptr.\ to val.
    131         & @T*[10]@
    132         & @T *x[10];@
    133         & @[ [10] * T ]@
    134         & @[ array(* T, 10) ]@
    135         \\ \hline
    136     & \pbox{20cm}{ \vspace{2pt} ar.\ of ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x[5]}}   }\vspace{2pt}
    137         & @T * const [10]@
    138         & @T * const x[10];@
    139         & @[ [10] const * T ]@
    140         & @[ array(const * T, 10) ]@
    141         \\ \hline
    142     & \pbox{20cm}{ \vspace{2pt} ar.\ of ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*(x[5])}}   }\vspace{2pt}
    143         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * [10]} \\ \lstinline{T const * [10]}   }
    144         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x[10];} \\ \lstinline{T const * x[10];}   }
    145         & @[ [10] * const T ]@
    146         & @[ array(* const T, 10) ]@
    147         \\ \hline
    148     $\triangleright$ & ptr.\ to ar.\ of val.
    149         & @T(*)[10]@
    150         & @T (*x)[10];@
    151         & @[ * [10] T ]@
    152         & @[ * array(T, 10) ]@
    153         \\ \hline
    154     & \pbox{20cm}{ \vspace{2pt} ptr.\ to ar.\ of val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}}   }\vspace{2pt}
    155         & @T(* const)[10]@
    156         & @T (* const x)[10];@
    157         & @[ const * [10] T ]@
    158         & @[ const * array(T, 10) ]@
    159         \\ \hline
    160     & \pbox{20cm}{ \vspace{2pt} ptr.\ to ar.\ of val.\\ \footnotesize{no writing the val.\ in \lstinline{(*x)[5]}}   }\vspace{2pt}
    161         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T(*)[10]} \\ \lstinline{T const (*) [10]}   }
    162         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T (*x)[10];} \\ \lstinline{T const (*x)[10];}   }
    163         & @[ * [10] const T ]@
    164         & @[ * const array(T, 10) ]@
    165         \\ \hline
    166     & ptr.\ to ar.\ of ptr.\ to val.
    167         & @T*(*)[10]@
    168         & @T *(*x)[10];@
    169         & @[ * [10] * T ]@
    170         & @[ * array(* T, 10) ]@
    171         \\ \hline
     196        & Description & Type & Declaration & \CFA-C  & \CFA-Full \\ \hline
     197        $\triangleright$ & val.
     198            & @T@
     199            & @T x;@
     200            & @[ T ]@
     201            &
     202            \\ \hline
     203        & \pbox{20cm}{ \vspace{2pt} val.\\ \footnotesize{no writing the val.\ in \lstinline{x}}   }\vspace{2pt}
     204            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T} \\ \lstinline{T const}   }
     205            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T x;} \\ \lstinline{T const x;}   }
     206            & @[ const T ]@
     207            &
     208            \\ \hline \hline
     209        $\triangleright$ & ptr.\ to val.
     210            & @T *@
     211            & @T * x;@
     212            & @[ * T ]@
     213            &
     214            \\ \hline
     215        & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}}   }\vspace{2pt}
     216            & @T * const@
     217            & @T * const x;@
     218            & @[ const * T ]@
     219            &
     220            \\ \hline
     221        & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*x}}   }\vspace{2pt}
     222            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T *} \\ \lstinline{T const *}   }
     223            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x;} \\ \lstinline{T const * x;}   }
     224            & @[ * const T ]@
     225            &
     226            \\ \hline \hline
     227        $\triangleright$ & ar.\ of val.
     228            & @T[10]@
     229            & @T x[10];@
     230            & @[ [10] T ]@
     231            & @[ array(T, 10) ]@
     232            \\ \hline
     233        & \pbox{20cm}{ \vspace{2pt} ar.\ of val.\\ \footnotesize{no writing the val.\ in \lstinline{x[5]}}   }\vspace{2pt}
     234            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T[10]} \\ \lstinline{T const[10]}   }
     235            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T x[10];} \\ \lstinline{T const x[10];}   }
     236            & @[ [10] const T ]@
     237            & @[ const array(T, 10) ]@
     238            \\ \hline
     239        & ar.\ of ptr.\ to val.
     240            & @T*[10]@
     241            & @T *x[10];@
     242            & @[ [10] * T ]@
     243            & @[ array(* T, 10) ]@
     244            \\ \hline
     245        & \pbox{20cm}{ \vspace{2pt} ar.\ of ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x[5]}}   }\vspace{2pt}
     246            & @T * const [10]@
     247            & @T * const x[10];@
     248            & @[ [10] const * T ]@
     249            & @[ array(const * T, 10) ]@
     250            \\ \hline
     251        & \pbox{20cm}{ \vspace{2pt} ar.\ of ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*(x[5])}}   }\vspace{2pt}
     252            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * [10]} \\ \lstinline{T const * [10]}   }
     253            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x[10];} \\ \lstinline{T const * x[10];}   }
     254            & @[ [10] * const T ]@
     255            & @[ array(* const T, 10) ]@
     256            \\ \hline \hline
     257        $\triangleright$ & ptr.\ to ar.\ of val.
     258            & @T(*)[10]@
     259            & @T (*x)[10];@
     260            & @[ * [10] T ]@
     261            & @[ * array(T, 10) ]@
     262            \\ \hline
     263        & \pbox{20cm}{ \vspace{2pt} ptr.\ to ar.\ of val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}}   }\vspace{2pt}
     264            & @T(* const)[10]@
     265            & @T (* const x)[10];@
     266            & @[ const * [10] T ]@
     267            & @[ const * array(T, 10) ]@
     268            \\ \hline
     269        & \pbox{20cm}{ \vspace{2pt} ptr.\ to ar.\ of val.\\ \footnotesize{no writing the val.\ in \lstinline{(*x)[5]}}   }\vspace{2pt}
     270            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T(*)[10]} \\ \lstinline{T const (*) [10]}   }
     271            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T (*x)[10];} \\ \lstinline{T const (*x)[10];}   }
     272            & @[ * [10] const T ]@
     273            & @[ * const array(T, 10) ]@
     274            \\ \hline
     275        & ptr.\ to ar.\ of ptr.\ to val.
     276            & @T*(*)[10]@
     277            & @T *(*x)[10];@
     278            & @[ * [10] * T ]@
     279            & @[ * array(* T, 10) ]@
     280            \\ \hline
    172281\end{tabular}
     282\caption{Figure}
     283\end{figure}
    173284
    174285
    175286\subsection{Arrays decay and pointers diffract}
    176287
    177 TODO: typeset
    178 \lstinputlisting[language=C, firstline=4, lastline=26]{bkgd-carray-decay.c}
    179 
     288The last section established the difference between these four types:
     289\lstinput{3-6}{bkgd-carray-decay.c}
     290But the expression used for obtaining the pointer to the first element is pedantic.
     291The root of all C programmer experience with arrays is the shortcut
     292\lstinput{8-8}{bkgd-carray-decay.c}
     293which reproduces @pa0@, in type and value:
     294\lstinput{9-9}{bkgd-carray-decay.c}
     295The validity of this initialization is unsettling, in the context of the facts established in the last section.
     296Notably, it initializes name @pa0x@ from expression @a@, when they are not of the same type:
     297\lstinput{10-10}{bkgd-carray-decay.c}
    180298
    181299So, C provides an implicit conversion from @float[10]@ to @float*@, as described in ARM-6.3.2.1.3:
    182 
    183300\begin{quote}
    184     Except when it is the operand of the @sizeof@ operator, or the unary @&@ operator, or is a
    185     string literal used to initialize an array
    186     an expression that has type ``array of type'' is
    187     converted to an expression with type ``pointer to type'' that points to the initial element of
    188     the array object
     301Except when it is the operand of the @sizeof@ operator, or the unary @&@ operator, or is a
     302string literal used to initialize an array
     303an expression that has type ``array of type'' is
     304converted to an expression with type ``pointer to type'' that points to the initial element of
     305the array object
    189306\end{quote}
    190307
     
    206323leads to an expectation that the runtime handling is uniform across legal and illegal accesses.
    207324Moreover, consider the common pattern of subscripting on a malloc result:
    208 \begin{lstlisting}
    209     float * fs = malloc( 10 * sizeof(float) );
    210     fs[5] = 3.14;
    211 \end{lstlisting}
     325\begin{cfa}
     326float * fs = malloc( 10 * sizeof(float) );
     327fs[5] = 3.14;
     328\end{cfa}
    212329The @malloc@ behaviour is specified as returning a pointer to ``space for an object whose size is'' as requested (ARM-7.22.3.4.2).
    213330But program says \emph{nothing} more about this pointer value, that might cause its referent to \emph{be} an array, before doing the subscript.
     
    229346the parameter's type becomes a type that I summarize as being the array-decayed type.
    230347The respective handlings of the following two parameter spellings shows that the array-spelled one is really, like the other, a pointer.
    231 \lstinputlisting[language=C, firstline=40, lastline=44]{bkgd-carray-decay.c}
     348\lstinput{12-16}{bkgd-carray-decay.c}
    232349As the @sizeof(x)@ meaning changed, compared with when run on a similarly-spelled local variariable declaration,
    233350GCC also gives this code the warning: ```sizeof' on array function parameter `x' will return size of `float *'.''
    234351
    235352The caller of such a function is left with the reality that a pointer parameter is a pointer, no matter how it's spelled:
    236 \lstinputlisting[language=C, firstline=60, lastline=63]{bkgd-carray-decay.c}
     353\lstinput{18-21}{bkgd-carray-decay.c}
    237354This fragment gives no warnings.
    238355
     
    240357Note the opposite meaning of this spelling now, compared with its use in local variable declarations.
    241358This point of confusion is illustrated in:
    242 \lstinputlisting[language=C, firstline=80, lastline=87]{bkgd-carray-decay.c}
     359\lstinput{23-30}{bkgd-carray-decay.c}
    243360The basic two meanings, with a syntactic difference helping to distinguish,
    244361are illustrated in the declarations of @ca@ vs.\ @cp@,
     
    252369In sumary, when a funciton is written with an array-typed parameter,
    253370\begin{itemize}
    254     \item an appearance of passing an array by value is always an incorrect understanding
    255     \item a dimension value, if any is present, is ignorred
    256     \item pointer decay is forced at the call site and the callee sees the parameter having the decayed type
     371        \item an appearance of passing an array by value is always an incorrect understanding
     372        \item a dimension value, if any is present, is ignorred
     373        \item pointer decay is forced at the call site and the callee sees the parameter having the decayed type
    257374\end{itemize}
    258375
    259376Pointer decay does not affect pointer-to-array types, because these are already pointers, not arrays.
    260377As a result, a function with a pointer-to-array parameter sees the parameter exactly as the caller does:
    261 \lstinputlisting[language=C, firstline=100, lastline=110]{bkgd-carray-decay.c}
    262 
     378\lstinput{32-42}{bkgd-carray-decay.c}
    263379
    264380\noindent
     
    268384(Parameter declaration; ``no writing'' refers to the callee's ability)
    269385
    270 \noindent
     386\begin{figure}
     387\centering
    271388\begin{tabular}{llllll}
    272     & Description & Type & Param. Decl & \CFA-C  \\ \hline
    273     $\triangleright$ & ptr.\ to val.
    274         & @T *@
    275         & \pbox{20cm}{ \vspace{2pt} \lstinline{T * x,} \\ \lstinline{T x[10],} \\ \lstinline{T x[],}   }\vspace{2pt}
    276         & \pbox{20cm}{ \vspace{2pt} \lstinline{[ * T ]} \\ \lstinline{[ [10] T ]} \\ \lstinline{[ [] T  ]}   }
    277         \\ \hline
    278     & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}}   }\vspace{2pt}
    279         & @T * const@
    280         & \pbox{20cm}{ \vspace{2pt} \lstinline{T * const x,} \\ \lstinline{T x[const 10],} \\ \lstinline{T x[const],}   }\vspace{2pt}
    281         & \pbox{20cm}{ \vspace{2pt} \lstinline{[ const * T ]} \\ \lstinline{[ [const 10] T ]} \\ \lstinline{[ [const] T  ]}   }
    282         \\ \hline
    283     & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*x}}   }\vspace{2pt}
    284         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T *} \\ \lstinline{T const *}   }
    285         & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x,} \\ \lstinline{T const * x,} \\ \lstinline{const T x[10],} \\ \lstinline{T const x[10],} \\ \lstinline{const T x[],} \\ \lstinline{T const x[],}   }\vspace{2pt}
    286         & \pbox{20cm}{ \vspace{2pt} \lstinline{[* const T]} \\ \lstinline{[ [10] const T ]} \\ \lstinline{[ [] const T  ]}   }
    287         \\ \hline
    288     $\triangleright$ & ptr.\ to ar.\ of val.
    289         & @T(*)[10]@
    290         & \pbox{20cm}{ \vspace{2pt} \lstinline{T (*x)[10],} \\ \lstinline{T x[3][10],} \\ \lstinline{T x[][10],}   }\vspace{2pt}
    291         & \pbox{20cm}{ \vspace{2pt} \lstinline{[* [10] T]} \\ \lstinline{[ [3] [10] T ]} \\ \lstinline{[ [] [10] T  ]}   }
    292         \\ \hline
    293     & ptr.\ to ptr.\ to val.
    294         & @T **@
    295         & \pbox{20cm}{ \vspace{2pt} \lstinline{T ** x,} \\ \lstinline{T *x[10],} \\ \lstinline{T *x[],}   }\vspace{2pt}
    296         & \pbox{20cm}{ \vspace{2pt} \lstinline{[ * * T ]} \\ \lstinline{[ [10] * T ]} \\ \lstinline{[ [] * T  ]}   }
    297         \\ \hline
    298     & \pbox{20cm}{ \vspace{2pt} ptr.\ to ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{**argv}}   }\vspace{2pt}
    299         & @const char **@
    300         & \pbox{20cm}{ \vspace{2pt} \lstinline{const char *argv[],} \\ \footnotesize{(others elided)}   }\vspace{2pt}
    301         & \pbox{20cm}{ \vspace{2pt} \lstinline{[ [] * const char ]} \\ \footnotesize{(others elided)}   }
    302         \\ \hline
     389        & Description & Type & Param. Decl & \CFA-C  \\ \hline
     390        $\triangleright$ & ptr.\ to val.
     391            & @T *@
     392            & \pbox{20cm}{ \vspace{2pt} \lstinline{T * x,} \\ \lstinline{T x[10],} \\ \lstinline{T x[],}   }\vspace{2pt}
     393            & \pbox{20cm}{ \vspace{2pt} \lstinline{[ * T ]} \\ \lstinline{[ [10] T ]} \\ \lstinline{[ [] T  ]}   }
     394            \\ \hline
     395        & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}}   }\vspace{2pt}
     396            & @T * const@
     397            & \pbox{20cm}{ \vspace{2pt} \lstinline{T * const x,} \\ \lstinline{T x[const 10],} \\ \lstinline{T x[const],}   }\vspace{2pt}
     398            & \pbox{20cm}{ \vspace{2pt} \lstinline{[ const * T ]} \\ \lstinline{[ [const 10] T ]} \\ \lstinline{[ [const] T  ]}   }
     399            \\ \hline
     400        & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*x}}   }\vspace{2pt}
     401            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T *} \\ \lstinline{T const *}   }
     402            & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x,} \\ \lstinline{T const * x,} \\ \lstinline{const T x[10],} \\ \lstinline{T const x[10],} \\ \lstinline{const T x[],} \\ \lstinline{T const x[],}   }\vspace{2pt}
     403            & \pbox{20cm}{ \vspace{2pt} \lstinline{[* const T]} \\ \lstinline{[ [10] const T ]} \\ \lstinline{[ [] const T  ]}   }
     404            \\ \hline \hline
     405        $\triangleright$ & ptr.\ to ar.\ of val.
     406            & @T(*)[10]@
     407            & \pbox{20cm}{ \vspace{2pt} \lstinline{T (*x)[10],} \\ \lstinline{T x[3][10],} \\ \lstinline{T x[][10],}   }\vspace{2pt}
     408            & \pbox{20cm}{ \vspace{2pt} \lstinline{[* [10] T]} \\ \lstinline{[ [3] [10] T ]} \\ \lstinline{[ [] [10] T  ]}   }
     409            \\ \hline
     410        & ptr.\ to ptr.\ to val.
     411            & @T **@
     412            & \pbox{20cm}{ \vspace{2pt} \lstinline{T ** x,} \\ \lstinline{T *x[10],} \\ \lstinline{T *x[],}   }\vspace{2pt}
     413            & \pbox{20cm}{ \vspace{2pt} \lstinline{[ * * T ]} \\ \lstinline{[ [10] * T ]} \\ \lstinline{[ [] * T  ]}   }
     414            \\ \hline
     415        & \pbox{20cm}{ \vspace{2pt} ptr.\ to ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{**argv}}   }\vspace{2pt}
     416            & @const char **@
     417            & \pbox{20cm}{ \vspace{2pt} \lstinline{const char *argv[],} \\ \footnotesize{(others elided)}   }\vspace{2pt}
     418            & \pbox{20cm}{ \vspace{2pt} \lstinline{[ [] * const char ]} \\ \footnotesize{(others elided)}   }
     419            \\ \hline
    303420\end{tabular}
    304 
     421\caption{Figure}
     422\end{figure}
    305423
    306424
     
    309427When the desired number of elements is unknown at compile time,
    310428a variable-length array is a solution:
    311 \begin{lstlisting}
    312     int main( int argc, const char *argv[] ) {
    313 
    314         assert( argc == 2 );
    315         size_t n = atol( argv[1] );
    316         assert( 0 < n && n < 1000 );
    317 
    318         float a[n];
    319         float b[10];
    320 
    321         // ... discussion continues here
    322     }
    323 \end{lstlisting}
    324 This arrangement allocates @n@ elements on the @main@ stack frame for @a@,
    325 just as it puts 10 elements on the @main@ stack frame for @b@.
     429\begin{cfa}
     430int main( int argc, const char *argv[] ) {
     431        assert( argc == 2 );
     432        size_t n = atol( argv[1] );
     433        assert( 0 < n && n < 1000 );
     434
     435        float a[n];
     436        float b[10];
     437
     438        // ... discussion continues here
     439}
     440\end{cfa}
     441This arrangement allocates @n@ elements on the @main@ stack frame for @a@, just as it puts 10 elements on the @main@ stack frame for @b@.
    326442The variable-sized allocation of @a@ is provided by @alloca@.
    327443
    328 In a situation where the array sizes are not known to be small enough
    329 for stack allocation to be sensible,
    330 corresponding heap allocations are achievable as:
    331 \begin{lstlisting}
    332     float *ax1 = malloc( sizeof( float[n] ) );
    333     float *ax2 = malloc( n * sizeof( float ) );
    334     float *bx1 = malloc( sizeof( float[1000000] ) );
    335     float *bx2 = malloc( 1000000 * sizeof( float ) );
    336 \end{lstlisting}
     444In a situation where the array sizes are not known to be small enough for stack allocation to be sensible, corresponding heap allocations are achievable as:
     445\begin{cfa}
     446float *ax1 = malloc( sizeof( float[n] ) );
     447float *ax2 = malloc( n * sizeof( float ) );
     448float *bx1 = malloc( sizeof( float[1000000] ) );
     449float *bx2 = malloc( 1000000 * sizeof( float ) );
     450\end{cfa}
    337451
    338452
     
    353467Just as an array's element type can be @float@, so can it be @float[10]@.
    354468
    355 While any of @float*@, @float[10]@ and @float(*)[10]@ are easy to tell apart from @float@,
    356 telling them apart from each other may need occasional reference back to TODO intro section.
     469While any of @float*@, @float[10]@ and @float(*)[10]@ are easy to tell apart from @float@, telling them apart from each other may need occasional reference back to TODO intro section.
    357470The sentence derived by wrapping each type in @-[3]@ follows.
    358471
     
    360473telling them apart from each other is what it takes to know what ``array of arrays'' really means.
    361474
    362 
    363475Pointer decay affects the outermost array only
    364476
    365 
    366477TODO: unfortunate syntactic reference with these cases:
    367478
    368479\begin{itemize}
    369     \item ar. of ar. of val (be sure about ordering of dimensions when the declaration is dropped)
    370     \item ptr. to ar. of ar. of val
     480        \item ar. of ar. of val (be sure about ordering of dimensions when the declaration is dropped)
     481        \item ptr. to ar. of ar. of val
    371482\end{itemize}
    372483
    373484
    374 
    375 
    376 
    377485\subsection{Arrays are (but) almost values}
    378486
     
    391499
    392500\subsection{Returning an array is (but) almost possible}
    393 
    394 
    395501
    396502
     
    414520which type information associated with a polymorphic return type
    415521replaces @malloc@'s use of programmer-supplied size information.
    416 \begin{lstlisting}
    417     // C, library
    418     void * malloc( size_t );
    419     // C, user
    420     struct tm * el1 = malloc(      sizeof(struct tm) );
    421     struct tm * ar1 = malloc( 10 * sizeof(struct tm) );
    422 
    423     // CFA, library
    424     forall( T * ) T * alloc();
    425     // CFA, user
    426     tm * el2 = alloc();
    427     tm (*ar2)[10] = alloc();
    428 \end{lstlisting}
     522\begin{cfa}
     523// C, library
     524void * malloc( size_t );
     525// C, user
     526struct tm * el1 = malloc(      sizeof(struct tm) );
     527struct tm * ar1 = malloc( 10 * sizeof(struct tm) );
     528
     529// CFA, library
     530forall( T * ) T * alloc();
     531// CFA, user
     532tm * el2 = alloc();
     533tm (*ar2)[10] = alloc();
     534\end{cfa}
    429535The alloc polymorphic return compiles into a hidden parameter, which receives a compiler-generated argument.
    430536This compiler's argument generation uses type information from the left-hand side of the initialization to obtain the intended type.
     
    436542In the last example, the choice of ``pointer to array'' @ar2@ breaks a parallel with @ar1@.
    437543They are not subscripted in the same way.
    438 \begin{lstlisting}
    439     ar1[5];
    440     (*ar2)[5];
    441 \end{lstlisting}
     544\begin{cfa}
     545ar1[5];
     546(*ar2)[5];
     547\end{cfa}
    442548Using ``reference to array'' works at resolving this issue.  TODO: discuss connection with Doug-Lea \CC proposal.
    443 \begin{lstlisting}
    444     tm (&ar3)[10] = *alloc();
    445     ar3[5];
    446 \end{lstlisting}
     549\begin{cfa}
     550tm (&ar3)[10] = *alloc();
     551ar3[5];
     552\end{cfa}
    447553The implicit size communication to @alloc@ still works in the same ways as for @ar2@.
    448554
     
    453559where the type requested is an array, making the result, much more obviously, an array object.
    454560
    455 The ``reference to array'' type has its sore spots too.  TODO see also @dimexpr-match-c/REFPARAM_CALL (under TRY_BUG_1)@
    456 
    457 
     561The ``reference to array'' type has its sore spots too.
     562TODO see also @dimexpr-match-c/REFPARAM_CALL@ (under @TRY_BUG_1@)
    458563
    459564TODO: I fixed a bug associated with using an array as a T.  I think.  Did I really?  What was the bug?
Note: See TracChangeset for help on using the changeset viewer.