Changeset 266732e for doc/theses/mike_brooks_MMath/background.tex
- Timestamp:
- Mar 9, 2024, 5:40:09 PM (2 months ago)
- Branches:
- master
- Children:
- b64d0f4
- Parents:
- 03606ce
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/mike_brooks_MMath/background.tex
r03606ce r266732e 21 21 This behaviour is typically one of 22 22 \begin{itemize} 23 24 25 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 26 26 \end{itemize} 27 27 28 28 The compiler whose program semantics is shown is 29 \begin{ lstlisting}29 \begin{cfa} 30 30 $ gcc --version 31 31 gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 32 \end{ lstlisting}32 \end{cfa} 33 33 running on Architecture @x86_64@, with the same environment targeted. 34 34 … … 39 39 \subsection{C reports many ill-typed expressions as warnings} 40 40 41 TODO: typeset 42 \lstinputlisting[language=C, firstline=13, lastline=56]{bkgd-c-tyerr.c} 41 These attempts to assign @y@ to @x@ and vice-versa are obviously ill-typed. 42 \lstinput{12-15}{bkgd-c-tyerr.c} 43 with warnings: 44 \begin{cfa} 45 warning: assignment to 'float *' from incompatible pointer type 'void (*)(void)' 46 warning: assignment to 'void (*)(void)' from incompatible pointer type 'float *' 47 \end{cfa} 48 Similarly, 49 \lstinput{17-19}{bkgd-c-tyerr.c} 50 with warning: 51 \begin{cfa} 52 warning: passing argument 1 of 'f' from incompatible pointer type 53 note: expected 'void (*)(void)' but argument is of type 'float *' 54 \end{cfa} 55 with a segmentation fault at runtime. 56 57 That @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@. 58 Rather, 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 60 A "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. 61 The behaviour (whose absence is unprovable) is neither minor nor unlikely. 62 The rejection shows that the program is ill-typed. 63 64 Yet, the rejection presents as a GCC warning. 65 66 In 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 43 69 44 70 … … 47 73 \subsection{C has an array type (!)} 48 74 49 TODO: typeset 50 \lstinputlisting[language=C, firstline=35, lastline=116]{bkgd-carray-arrty.c} 75 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.'' 76 Its qualities become apparent by inspecting the declaration 77 \lstinput{34-34}{bkgd-carray-arrty.c} 78 The inspection begins by using @sizeof@ to provide definite program semantics for the intuition of an expression's type. 79 Assuming a target platform keeps things concrete: 80 \lstinput{35-36}{bkgd-carray-arrty.c} 81 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). 82 \lstinput{37-40}{bkgd-carray-arrty.c} 83 That @a@ takes up 40 bytes is common reasoning for C programmers. 84 Set aside for a moment the claim that this first assertion is giving information about a type. 85 For now, note that an array and a pointer to its first element are, sometimes, different things. 86 87 The idea that there is such a thing as a pointer to an array may be surprising. 88 It is not the same thing as a pointer to the first element: 89 \lstinput{42-45}{bkgd-carray-arrty.c} 90 The first gets 91 \begin{cfa} 92 warning: assignment to `float (*)[10]' from incompatible pointer type `float *' 93 \end{cfa} 94 and the second gets the opposite. 95 96 We now refute a concern that @sizeof(a)@ is reporting on special knowledge from @a@ being an local variable, 97 say that it is informing about an allocation, rather than simply a type. 98 99 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: 100 \lstinput{46-50}{bkgd-carray-arrty.c} 101 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. 102 \lstinput{51-57}{bkgd-carray-arrty.c} 103 So, 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 105 A shortened form for declaring local variables exists, provided that length information is given in the initializer: 106 \lstinput{59-63}{bkgd-carray-arrty.c} 107 In 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 151 void stx2() { const T x[10]; 152 // x[5] = 3.14; // bad 153 } 154 void stx3() { T const x[10]; 155 // x[5] = 3.14; // bad 156 } 157 \end{cfa} 51 158 52 159 My contribution is enabled by recognizing 53 160 \begin{itemize} 54 55 56 57 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]@. 58 165 \end{itemize} 59 166 … … 75 182 a declaration is always the type followed by the declared identifier name; 76 183 for the example of letting @x@ be a \emph{pointer to array}, the declaration is spelled: 77 \begin{ lstlisting}184 \begin{cfa} 78 185 [ * [10] T ] x; 79 \end{ lstlisting}186 \end{cfa} 80 187 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. 81 188 … … 83 190 \textbf{Unfortunate Syntactic Reference} 84 191 85 \noindent 192 \begin{figure} 193 \centering 194 \setlength{\tabcolsep}{3pt} 86 195 \begin{tabular}{llllll} 87 88 89 90 91 92 93 94 95 96 97 98 99 \\\hline100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 \\\hline118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 \\\hline148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 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 172 281 \end{tabular} 282 \caption{Figure} 283 \end{figure} 173 284 174 285 175 286 \subsection{Arrays decay and pointers diffract} 176 287 177 TODO: typeset 178 \lstinputlisting[language=C, firstline=4, lastline=26]{bkgd-carray-decay.c} 179 288 The last section established the difference between these four types: 289 \lstinput{3-6}{bkgd-carray-decay.c} 290 But the expression used for obtaining the pointer to the first element is pedantic. 291 The root of all C programmer experience with arrays is the shortcut 292 \lstinput{8-8}{bkgd-carray-decay.c} 293 which reproduces @pa0@, in type and value: 294 \lstinput{9-9}{bkgd-carray-decay.c} 295 The validity of this initialization is unsettling, in the context of the facts established in the last section. 296 Notably, it initializes name @pa0x@ from expression @a@, when they are not of the same type: 297 \lstinput{10-10}{bkgd-carray-decay.c} 180 298 181 299 So, C provides an implicit conversion from @float[10]@ to @float*@, as described in ARM-6.3.2.1.3: 182 183 300 \begin{quote} 184 185 186 187 188 301 Except when it is the operand of the @sizeof@ operator, or the unary @&@ operator, or is a 302 string literal used to initialize an array 303 an expression that has type ``array of type'' is 304 converted to an expression with type ``pointer to type'' that points to the initial element of 305 the array object 189 306 \end{quote} 190 307 … … 206 323 leads to an expectation that the runtime handling is uniform across legal and illegal accesses. 207 324 Moreover, consider the common pattern of subscripting on a malloc result: 208 \begin{ lstlisting}209 210 211 \end{ lstlisting}325 \begin{cfa} 326 float * fs = malloc( 10 * sizeof(float) ); 327 fs[5] = 3.14; 328 \end{cfa} 212 329 The @malloc@ behaviour is specified as returning a pointer to ``space for an object whose size is'' as requested (ARM-7.22.3.4.2). 213 330 But program says \emph{nothing} more about this pointer value, that might cause its referent to \emph{be} an array, before doing the subscript. … … 229 346 the parameter's type becomes a type that I summarize as being the array-decayed type. 230 347 The respective handlings of the following two parameter spellings shows that the array-spelled one is really, like the other, a pointer. 231 \lstinput listing[language=C, firstline=40, lastline=44]{bkgd-carray-decay.c}348 \lstinput{12-16}{bkgd-carray-decay.c} 232 349 As the @sizeof(x)@ meaning changed, compared with when run on a similarly-spelled local variariable declaration, 233 350 GCC also gives this code the warning: ```sizeof' on array function parameter `x' will return size of `float *'.'' 234 351 235 352 The caller of such a function is left with the reality that a pointer parameter is a pointer, no matter how it's spelled: 236 \lstinput listing[language=C, firstline=60, lastline=63]{bkgd-carray-decay.c}353 \lstinput{18-21}{bkgd-carray-decay.c} 237 354 This fragment gives no warnings. 238 355 … … 240 357 Note the opposite meaning of this spelling now, compared with its use in local variable declarations. 241 358 This point of confusion is illustrated in: 242 \lstinput listing[language=C, firstline=80, lastline=87]{bkgd-carray-decay.c}359 \lstinput{23-30}{bkgd-carray-decay.c} 243 360 The basic two meanings, with a syntactic difference helping to distinguish, 244 361 are illustrated in the declarations of @ca@ vs.\ @cp@, … … 252 369 In sumary, when a funciton is written with an array-typed parameter, 253 370 \begin{itemize} 254 255 256 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 257 374 \end{itemize} 258 375 259 376 Pointer decay does not affect pointer-to-array types, because these are already pointers, not arrays. 260 377 As 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} 263 379 264 380 \noindent … … 268 384 (Parameter declaration; ``no writing'' refers to the callee's ability) 269 385 270 \noindent 386 \begin{figure} 387 \centering 271 388 \begin{tabular}{llllll} 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 \\\hline288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 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 303 420 \end{tabular} 304 421 \caption{Figure} 422 \end{figure} 305 423 306 424 … … 309 427 When the desired number of elements is unknown at compile time, 310 428 a 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} 430 int 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} 441 This arrangement allocates @n@ elements on the @main@ stack frame for @a@, just as it puts 10 elements on the @main@ stack frame for @b@. 326 442 The variable-sized allocation of @a@ is provided by @alloca@. 327 443 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} 444 In 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} 446 float *ax1 = malloc( sizeof( float[n] ) ); 447 float *ax2 = malloc( n * sizeof( float ) ); 448 float *bx1 = malloc( sizeof( float[1000000] ) ); 449 float *bx2 = malloc( 1000000 * sizeof( float ) ); 450 \end{cfa} 337 451 338 452 … … 353 467 Just as an array's element type can be @float@, so can it be @float[10]@. 354 468 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. 469 While 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. 357 470 The sentence derived by wrapping each type in @-[3]@ follows. 358 471 … … 360 473 telling them apart from each other is what it takes to know what ``array of arrays'' really means. 361 474 362 363 475 Pointer decay affects the outermost array only 364 476 365 366 477 TODO: unfortunate syntactic reference with these cases: 367 478 368 479 \begin{itemize} 369 370 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 371 482 \end{itemize} 372 483 373 484 374 375 376 377 485 \subsection{Arrays are (but) almost values} 378 486 … … 391 499 392 500 \subsection{Returning an array is (but) almost possible} 393 394 395 501 396 502 … … 414 520 which type information associated with a polymorphic return type 415 521 replaces @malloc@'s use of programmer-supplied size information. 416 \begin{ lstlisting}417 418 419 420 421 422 423 424 425 426 427 428 \end{ lstlisting}522 \begin{cfa} 523 // C, library 524 void * malloc( size_t ); 525 // C, user 526 struct tm * el1 = malloc( sizeof(struct tm) ); 527 struct tm * ar1 = malloc( 10 * sizeof(struct tm) ); 528 529 // CFA, library 530 forall( T * ) T * alloc(); 531 // CFA, user 532 tm * el2 = alloc(); 533 tm (*ar2)[10] = alloc(); 534 \end{cfa} 429 535 The alloc polymorphic return compiles into a hidden parameter, which receives a compiler-generated argument. 430 536 This compiler's argument generation uses type information from the left-hand side of the initialization to obtain the intended type. … … 436 542 In the last example, the choice of ``pointer to array'' @ar2@ breaks a parallel with @ar1@. 437 543 They are not subscripted in the same way. 438 \begin{ lstlisting}439 440 441 \end{ lstlisting}544 \begin{cfa} 545 ar1[5]; 546 (*ar2)[5]; 547 \end{cfa} 442 548 Using ``reference to array'' works at resolving this issue. TODO: discuss connection with Doug-Lea \CC proposal. 443 \begin{ lstlisting}444 445 446 \end{ lstlisting}549 \begin{cfa} 550 tm (&ar3)[10] = *alloc(); 551 ar3[5]; 552 \end{cfa} 447 553 The implicit size communication to @alloc@ still works in the same ways as for @ar2@. 448 554 … … 453 559 where the type requested is an array, making the result, much more obviously, an array object. 454 560 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 561 The ``reference to array'' type has its sore spots too. 562 TODO see also @dimexpr-match-c/REFPARAM_CALL@ (under @TRY_BUG_1@) 458 563 459 564 TODO: 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.