Changes in / [d9bad51:cb98d9d]
- Location:
- doc/theses/mike_brooks_MMath
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/mike_brooks_MMath/background.tex
rd9bad51 rcb98d9d 45 45 Hence, in all cases, @sizeof@ is informing about type information. 46 46 47 So, thinking of an array as a pointer to its first element is too simplistic an analogue and it is not backed up the type system.48 This misguided analogue can be forced onto single-dimension arraysbut there is no advantage other than possibly teaching beginning programmers about basic runtime array-access.49 50 Continuing, a short ened form for declaring local variables exists, provided that length information is given in the initializer:47 So, thinking of an array as a pointer to its first element is too simplistic an analogue and it is not backed up by the type system. 48 This misguided analogue works for a single-dimension array but there is no advantage other than possibly teaching beginning programmers about basic runtime array-access. 49 50 Continuing, a short form for declaring array variables exists using length information provided implicitly by an initializer. 51 51 \lstinput{59-62}{bkgd-carray-arrty.c} 52 In these declarations, the resulting types are both arrays, but their lengths are inferred. 53 54 My contribution is enabled by recognizing 52 The compiler counts the number of initializer elements and uses this value as the first dimension. 53 Unfortunately, the implicit element counting does not extend to dimensions beyond the first. 54 \lstinput{64-67}{bkgd-carray-arrty.c} 55 56 My contribution is recognizing: 55 57 \begin{itemize} 56 \item There is value in using a type that knows how big the whole thing is.58 \item There is value in using a type that knows its size. 57 59 \item The type pointer to (first) element does not. 58 60 \item C \emph{has} a type that knows the whole picture: array, e.g. @T[10]@. 59 \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]@. 61 \item This type has all the usual derived forms, which also know the whole picture. 62 A usefully noteworthy example is pointer to array, e.g. @T (*)[10]@.\footnote{ 63 The parenthesis are necessary because subscript has higher priority than pointer in C declarations. 64 (Subscript also has higher priority than dereference in C expressions.)} 60 65 \end{itemize} 61 66 62 Each of these sections, which introduces another layer of of the C arrays' story, 63 concludes with an \emph{Unfortunate Syntactic Reference}. 64 It shows how to spell the types under discussion, 65 along with interactions with orthogonal (but easily confused) language features. 67 The following sections introduce the many layers of the C array story, concluding with an \emph{Unfortunate Syntactic Reference}. 68 It shows how to define (spell) the types under discussion, along with interactions with orthogonal (but easily confused) language features. 66 69 Alternate spellings are listed within a row. 67 70 The simplest occurrences of types distinguished in the preceding discussion are marked with $\triangleright$. … … 78 81 for the example of letting @x@ be a \emph{pointer to array}, the declaration is spelled: 79 82 \begin{cfa} 80 [ * [10] T ]x;83 * [10] T x; 81 84 \end{cfa} 82 85 The \CFA-Full column gives the spelling of a different type, introduced in TODO, which has all of my contributed improvements for safety and ergonomics. 86 87 Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site. 88 For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way: 89 \begin{cfa} 90 int @(*@f@())[@5@]@ {...}; $\C{// definition}$ 91 ... @(*@f@())[@3@]@ += 1; $\C{// usage}$ 92 \end{cfa} 93 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}). 94 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice, even though Dennis Richie believed otherwise: 95 \begin{quote} 96 In spite of its difficulties, I believe that the C's approach to declarations remains plausible, and am comfortable with it; it is a useful unifying principle.~\cite[p.~12]{Ritchie93} 97 \end{quote} 98 99 \CFA provides its own type, variable and routine declarations, using a different syntax. 100 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type. 101 In the following example, {\color{red}red} is the base type and {\color{blue}blue} is qualifiers. 102 The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type. 103 \begin{cquote} 104 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 105 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}} \\ 106 \begin{cfa}[moredelim={**[is][\color{blue}]{\#}{\#}}] 107 @int@ #*# x1 #[5]#; 108 @int@ #(*#x2#)[5]#; 109 #int (*#f@( int p )@#)[5]#; 110 \end{cfa} 111 & 112 \begin{cfa}[moredelim={**[is][\color{blue}]{\#}{\#}}] 113 #[5] *# @int@ x1; 114 #* [5]# @int@ x2; 115 #[* [5] int]# f@( int p )@; 116 \end{cfa} 117 \end{tabular} 118 \end{cquote} 83 119 84 120 \VRef[Figure]{bkgd:ar:usr:avp} gives this reference for the discussion so far. … … 87 123 \centering 88 124 \setlength{\tabcolsep}{3pt} 89 \begin{tabular}{llllll} 90 & Description & Type & Declaration & \CFA-C & \CFA-Full \\ \hline 91 $\triangleright$ & val. 92 & @T@ 93 & @T x;@ 94 & @[ T ]@ 95 & 96 \\ \hline 97 & \pbox{20cm}{ \vspace{2pt} val.\\ \footnotesize{no writing the val.\ in \lstinline{x}} }\vspace{2pt} 98 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T} \\ \lstinline{T const} } 99 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T x;} \\ \lstinline{T const x;} } 100 & @[ const T ]@ 101 & 102 \\ \hline \hline 103 $\triangleright$ & ptr.\ to val. 104 & @T *@ 105 & @T * x;@ 106 & @[ * T ]@ 107 & 108 \\ \hline 109 & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}} }\vspace{2pt} 110 & @T * const@ 111 & @T * const x;@ 112 & @[ const * T ]@ 113 & 114 \\ \hline 115 & \pbox{20cm}{ \vspace{2pt} ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*x}} }\vspace{2pt} 116 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T *} \\ \lstinline{T const *} } 117 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x;} \\ \lstinline{T const * x;} } 118 & @[ * const T ]@ 119 & 120 \\ \hline \hline 121 $\triangleright$ & ar.\ of val. 122 & @T[10]@ 123 & @T x[10];@ 124 & @[ [10] T ]@ 125 & @[ array(T, 10) ]@ 126 \\ \hline 127 & \pbox{20cm}{ \vspace{2pt} ar.\ of val.\\ \footnotesize{no writing the val.\ in \lstinline{x[5]}} }\vspace{2pt} 128 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T[10]} \\ \lstinline{T const[10]} } 129 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T x[10];} \\ \lstinline{T const x[10];} } 130 & @[ [10] const T ]@ 131 & @[ const array(T, 10) ]@ 132 \\ \hline 133 & ar.\ of ptr.\ to val. 134 & @T*[10]@ 135 & @T *x[10];@ 136 & @[ [10] * T ]@ 137 & @[ array(* T, 10) ]@ 138 \\ \hline 139 & \pbox{20cm}{ \vspace{2pt} ar.\ of ptr.\ to val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x[5]}} }\vspace{2pt} 140 & @T * const [10]@ 141 & @T * const x[10];@ 142 & @[ [10] const * T ]@ 143 & @[ array(const * T, 10) ]@ 144 \\ \hline 145 & \pbox{20cm}{ \vspace{2pt} ar.\ of ptr.\ to val.\\ \footnotesize{no writing the val.\ in \lstinline{*(x[5])}} }\vspace{2pt} 146 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * [10]} \\ \lstinline{T const * [10]} } 147 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T * x[10];} \\ \lstinline{T const * x[10];} } 148 & @[ [10] * const T ]@ 149 & @[ array(* const T, 10) ]@ 150 \\ \hline \hline 151 $\triangleright$ & ptr.\ to ar.\ of val. 152 & @T(*)[10]@ 153 & @T (*x)[10];@ 154 & @[ * [10] T ]@ 155 & @[ * array(T, 10) ]@ 156 \\ \hline 157 & \pbox{20cm}{ \vspace{2pt} ptr.\ to ar.\ of val.\\ \footnotesize{no writing the ptr.\ in \lstinline{x}} }\vspace{2pt} 158 & @T(* const)[10]@ 159 & @T (* const x)[10];@ 160 & @[ const * [10] T ]@ 161 & @[ const * array(T, 10) ]@ 162 \\ \hline 163 & \pbox{20cm}{ \vspace{2pt} ptr.\ to ar.\ of val.\\ \footnotesize{no writing the val.\ in \lstinline{(*x)[5]}} }\vspace{2pt} 164 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T(*)[10]} \\ \lstinline{T const (*) [10]} } 165 & \pbox{20cm}{ \vspace{2pt} \lstinline{const T (*x)[10];} \\ \lstinline{T const (*x)[10];} } 166 & @[ * [10] const T ]@ 167 & @[ * const array(T, 10) ]@ 168 \\ \hline 169 & ptr.\ to ar.\ of ptr.\ to val. 170 & @T*(*)[10]@ 171 & @T *(*x)[10];@ 172 & @[ * [10] * T ]@ 173 & @[ * array(* T, 10) ]@ 174 \\ \hline 125 \begin{tabular}{ll|l|l|l|l} 126 & Description & Type & Declaration & \CFA & \CFA-thesis \\ \hline 127 $\triangleright$ & val. & @T@ & @T x;@ & @T@ & \\ 128 \hline 129 & immutable val. & @const T@ & @T const x;@ & @const T@ & \\ 130 & & @T const@ & @T const x;@ & @T const@ & \\ 131 \hline \hline 132 $\triangleright$ & ptr.\ to val. & @T *@ & @T * x;@ & @* T@ & \\ 133 \hline 134 & immutable ptr. to val. & @T * const@ & @T * const x;@ & @const * T@ & \\ 135 \hline 136 & ptr. to immutable val. & @const T *@ & @const T * x;@ & @* const T@ & \\ 137 & & @T const *@ & @T const * x;@ & @* T const@ & \\ 138 \hline \hline 139 $\triangleright$ & ar.\ of val. & @T[10]@ & @T x[10];@ & @[10] T@ & @array(T, 10)@ \\ 140 \hline 141 & ar.\ of immutable val. & @const T[10]@ & @const T x[10];@ & @[10] const T@ & @const array(T, 10)@ \\ 142 & & @T const [10]@ & @T const x[10];@ & @[10] T const@ & @array(T, 10) const@ \\ 143 \hline 144 & ar.\ of ptr.\ to val. & @T * [10]@ & @T * x[10];@ & @[10] * T@ & @array(T * | * T, 10)@ \\ 145 \hline 146 & ar.\ of imm. ptr.\ to val. & @T * const [10]@ & @T * const x[10];@ & @[10] const * T@ & @array(const * T, 10)@ \\ 147 \hline 148 & ar.\ of ptr.\ to imm. val. & @const T * [10]@ & @const T * x[10];@ & @[10] * const T@ & @array(* const T, 10)@ \\ 149 & & @T const * [10]@ & @T const * x[10];@ & @[10] * T const@ & @array(* T const, 10)@ \\ 150 \hline \hline 151 $\triangleright$ & ptr.\ to ar.\ of val. & @T(*)[10]@ & @T (*x)[10];@ & @* [10] T@ & @* array(T, 10)@ \\ 152 \hline 153 & imm. ptr.\ to ar.\ of val. & @T(* const)[10]@ & @T (* const x)[10];@ & @const * [10] T@ & @const * array(T, 10)@ \\ 154 \hline 155 & ptr.\ to ar.\ of imm. val. & @const T(*)[10]@ & @const T (*x)[10];@ & @* [10] const T@ & @* const array(T, 10)@ \\ 156 & & @T const (*) [10]}@ & @T const (*x)[10];@ & @* [10] T const@ & @* array(T, 10) const@ \\ 157 \hline 158 & ptr.\ to ar.\ of ptr.\ to val. & @T*(*)[10]@ & @T *(*x)[10];@ & @* [10] * T@ & @* array(T * | * T, 10)@ \\ 159 \hline 175 160 \end{tabular} 176 161 \caption{Unfortunate Syntactic Reference for Array vs Pointer. Includes interaction with constness.} … … 251 236 ARM-6.7.6.3.7 explains that when an array type is written for a parameter, 252 237 the parameter's type becomes a type that I summarize as being the array-decayed type. 253 The respective handling sof the following two parameter spellings shows that the array-spelled one is really, like the other, a pointer.238 The respective handling of the following two parameter spellings shows that the array-spelled one is really, like the other, a pointer. 254 239 \lstinput{12-16}{bkgd-carray-decay.c} 255 240 As the @sizeof(x)@ meaning changed, compared with when run on a similarly-spelled local variable declaration, … … 284 269 \lstinput{32-42}{bkgd-carray-decay.c} 285 270 286 \VRef[Figure]{bkgd:ar:usr:decay-parm} gives the reference for the decay phenomenon seen in parameter dec alarations.271 \VRef[Figure]{bkgd:ar:usr:decay-parm} gives the reference for the decay phenomenon seen in parameter declarations. 287 272 288 273 \begin{figure} -
doc/theses/mike_brooks_MMath/programs/bkgd-carray-arrty.c
rd9bad51 rcb98d9d 57 57 f( &ar ); 58 58 59 float fs[] = {3.14, 1.7 07};59 float fs[] = {3.14, 1.77}; 60 60 char cs[] = "hello"; 61 61 static_assert( sizeof(fs) == 2 * sizeof(float) ); 62 62 static_assert( sizeof(cs) == 6 * sizeof(char) ); $\C{// 5 letters + 1 null terminator}$ 63 63 64 float fm[][2] = { {3.14, 1.77}, {12.4, 0.01}, {7.8, 1.23} }; $\C{// brackets define structuring}$ 65 char cm[][sizeof("hello")] = { "hello", "hello", "hello" }; 66 static_assert( sizeof(fm) == 3 * 2 * sizeof(float) ); 67 static_assert( sizeof(cm) == 3 * 6 * sizeof(char) ); 64 68 } 65 69
Note: See TracChangeset
for help on using the changeset viewer.