Changeset f2b74e3
- Timestamp:
- Dec 9, 2025, 5:23:33 PM (10 hours ago)
- Branches:
- master
- Parents:
- 79ec8c3
- Location:
- doc/theses/mike_brooks_MMath
- Files:
-
- 1 added
- 5 edited
-
background.tex (modified) (41 diffs)
-
papers/Final-ONCD-Technical-Report.pdf (added)
-
programs/bkgd-c-tyerr.c (modified) (1 diff)
-
programs/bkgd-carray-decay.c (modified) (2 diffs)
-
programs/bkgd-carray-mdim.c (modified) (1 diff)
-
programs/lst-issues-multi-static.run.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/mike_brooks_MMath/background.tex
r79ec8c3 rf2b74e3 7 7 8 8 C reports many ill-typed expressions as warnings. 9 For example, these attempts to assign @y@ to @x@ and vice-versa are obviouslyill-typed.9 For example, these attempts to assign @y@ to @x@ and vice-versa are ill-typed. 10 10 \lstinput{12-15}{bkgd-c-tyerr.c} 11 11 with warnings: … … 21 21 note: expected 'void (*)(void)' but argument is of type 'float *' 22 22 \end{cfa} 23 with a segmentation fault at runtime.24 23 Clearly, @gcc@ understands these ill-typed case, and yet allows the program to compile, which seems inappropriate. 25 24 Compiling with flag @-Werror@, which turns warnings into errors, is often too pervasive, because some warnings are just warnings, \eg an unused variable. … … 87 86 (\VRef{s:ArraysDecay} shows pointer decay allows the first form to be written @pa[i] += 1@, which is further syntax confusion.) 88 87 Again, if the priorities were reversed, the expressions become more intuitive: @*pa[i] += 1@ and @*(ap[i]) += 1@. 89 Note, a similar priority inversion exists between deference @*@ and field selection @.@(period), so @*ps.f@ means @*(ps.f)@;88 Note, a similar priority inversion exists between deference '@*@' and field selection '@.@' (period), so @*ps.f@ means @*(ps.f)@; 90 89 this anomaly is \emph{fixed} with operator @->@, which performs the two operations in the more intuitive order: @sp->f@ $\Rightarrow$ @(*sp).f@. 91 90 \end{itemize} … … 128 127 As declaration size increases, it becomes corresponding difficult to read and understand the C form, whereas reading and understanding a \CFA declaration has linear complexity. 129 128 Note, writing declarations left to right is common in other programming languages, where the function return-type is often placed after the parameter declarations, \eg \CC \lstinline[language=C++]{auto f( int ) -> int}. 130 (Note, putting the return type at the end deviates from where the return value logically appears in an expression, @x = f(...)@ versus @f(...) = x@.) 129 However, putting the return type at the end deviates from where the return value logically appears in an expression, @x = f(...)@ versus @f(...) = x@. 131 130 Interestingly, programmers normally speak a declaration from left to right, regardless of how it is written. 132 131 (It is unclear if Hebrew or Arabic speakers, say declarations right to left.) 133 132 134 \VRef[Table]{bkgd:ar:usr:avp} introduces the many layers of the C and \CFA array story, where the \CFA story is discussion in \VRef[Chapter]{c:Array}.133 Specifically, \VRef[Table]{bkgd:ar:usr:avp} introduces the many layers of the C and \CFA array story, where the \CFA story is discussion in \VRef[Chapter]{c:Array}. 135 134 The \CFA-thesis column shows the new array declaration form, which is my contribution to safety and ergonomics. 136 135 The table shows there are multiple yet equivalent forms for the array types under discussion, and subsequent discussion shows interactions with orthogonal (but easily confused) language features. … … 138 137 The simplest occurrences of types distinguished in the preceding discussion are marked with $\triangleright$. 139 138 Removing the declared variable @x@, gives the type used for variable, structure field, cast, or error messages. 140 Unfortunately, parameter declarations have more syntactic forms and rules .139 Unfortunately, parameter declarations have more syntactic forms and rules \see{Section~\ref{s:ArraysDecay}~\VPageref{p:ParameterDeclarations}}. 141 140 142 141 \begin{table} … … 144 143 \caption{Syntactic Reference for Array vs Pointer. Includes interaction with \lstinline{const}ness.} 145 144 \label{bkgd:ar:usr:avp} 146 \begin{tabular}{ll|l|l|l} 145 \setlength{\tabcolsep}{12pt} 146 \begin{tabular}{@{}ll|l|l|l@{}} 147 147 & Description & \multicolumn{1}{c|}{C} & \multicolumn{1}{c|}{\CFA} & \multicolumn{1}{c}{\CFA-thesis} \\ 148 148 \hline … … 253 253 Using the type form yields the same results as the prior expression form. 254 254 \lstinput{46-49}{bkgd-carray-arrty.c} 255 The results are also the same when there is no allocation at all .255 The results are also the same when there is no allocation at all, \eg a parameter declaration. 256 256 This time, starting from a pointer-to-array type: 257 257 \lstinput{51-57}{bkgd-carray-arrty.c} … … 297 297 ``pointer to \emph{type}'' that points to the initial element of the array object~\cite[\S~6.3.2.1.3]{C11} 298 298 \end{quote} 299 This phenomenon is the famous \newterm{pointer decay}, which is a decay of an array-typed expression into a pointer-typed one.299 This phenomenon is the famous (infamous) \newterm{pointer decay}, which is a decay of an array-typed expression into a pointer-typed one. 300 300 It is worthy to note that the list of exceptional cases does not feature the occurrence of @ar@ in @ar[i]@. 301 301 Thus, subscripting happens on pointers not arrays. … … 305 305 \cite[\S~6.5.6.8]{C11} explains that the addition, of a pointer with an integer type, is defined only when the pointer refers to an element that is in an array, with a meaning of @i@ elements away from, which is valid if @ar@ is big enough and @i@ is small enough. 306 306 Finally, \cite[\S~6.5.3.2.4]{C11} explains that the @*@ operator's result is the referenced element. 307 Taken together, these rules illustrate that @ar[i]@ and @i[a]@ mean the same thing !307 Taken together, these rules illustrate that @ar[i]@ and @i[a]@ mean the same thing, as plus is commutative. 308 308 309 309 Subscripting a pointer when the target is standard-inappropriate is still practically well-defined. … … 318 318 But \emph{nothing} more is said about this pointer value, specifically that its referent might \emph{be} an array allowing subscripting. 319 319 320 Under this assumption, a pointer being subscripted (or added to, then dereferenced) by any value (positive, zero, or negative), gives a view of the program's entire address space, centred around the @p@ address, divided into adjacent @sizeof(*p)@ chunks, each potentially (re)interpreted as @typeof(*p)@.321 I call this phenomenon \emph{array diffraction}, which is a diffraction of a single-element pointer into the assumption that its target is in the middle of an array whose size is unlimited in both directions.320 Under this assumption, a pointer, @p@, being subscripted (or added to, then dereferenced) by any value (positive, zero, or negative), gives a view of the program's entire address space, centred around @p@'s address, divided into adjacent @sizeof(*p)@ chunks, each potentially (re)interpreted as @typeof(*p).t@. 321 I call this phenomenon \emph{array diffraction}, which is a diffraction of a single-element pointer into the assumption that its target is conceptually in the middle of an array whose size is unlimited in both directions. 322 322 No pointer is exempt from array diffraction. 323 323 No array shows its elements without pointer decay. 324 324 325 \label{p:ParameterDeclarations} 325 326 A further pointer--array confusion, closely related to decay, occurs in parameter declarations. 326 327 \cite[\S~6.7.6.3.7]{C11} explains that when an array type is written for a parameter, … … 379 380 \label{bkgd:ar:usr:decay-parm} 380 381 \centering 381 \begin{tabular}{llllll} 382 \setlength{\tabcolsep}{10pt} 383 \begin{tabular}{@{}llllll@{}} 382 384 & Description & Type & Parameter Declaration & \CFA \\ 383 385 \hline … … 426 428 Unfortunately, there is significant misinformation about VLAs, \eg the stack size is limited (small), or VLAs cause stack failures or are inefficient. 427 429 VLAs exist as far back as Algol W~\cite[\S~5.2]{AlgolW} and are a sound and efficient data type. 430 Most shells limit the maximum stack size to guard against infinite recursion, but the stack size can be set to unlimited, just like the heap. 428 431 For types with a dynamic-fixed stack, \eg coroutines or user-level threads, large VLAs can overflow the stack without appropriately sizing the stack, so heap allocation is used when the array size is unbounded. 429 432 … … 436 439 When working with arrays, \eg linear algebra, array dimensions are referred to as \emph{rows} and \emph{columns} for a matrix, adding \emph{planes} for a cube. 437 440 (There is little terminology for higher dimensional arrays.) 438 For example, an acrostic poem\footnote{A type of poetry where the first, last or other letters in a line spell out a particularword or phrase in a vertical column.}441 For example, an acrostic poem\footnote{A kind of poetry where the first, last or other letters in a line spell out a word or phrase in a vertical column.} 439 442 can be treated as a grid of characters, where the rows are the text and the columns are the embedded keyword(s). 440 443 Within a poem, there is the concept of a \newterm{slice}, \eg a row is a slice for the poem text, a column is a slice for a keyword. … … 510 513 For example, an array-of-array may be an array of row pointers to arrays of columns, so the rows may not be contiguous in memory nor even the same length (triangular matrix). 511 514 Regardless, there is usually a uniform subscripting syntax masking the memory layout, even though a language could differentiated between the two forms using subscript syntax, \eg @m[1,2]@ \vs @aa[1][2]@. 512 Nevertheless, controlling memory layout can make a difference in what operations are allowed and in performance (caching/NUMA effects). 513 514 C also provides non-contiguous arrays-of-arrays. 515 Nevertheless, controlling memory layout can make a difference in what operations are allowed and in performance (\eg caching/NUMA effects). 516 C also provides non-contiguous arrays-of-arrays: 515 517 \begin{cfa} 516 518 int m[5][5]; $\C{// contiguous}$ 517 519 int * aa[5]; $\C{// non-contiguous}$ 518 520 \end{cfa} 519 both with different memory layout using the same subscripting, and both with different degrees of issues. 521 both with different memory layout using the same subscripting and different degrees of issues. 522 520 523 The focus of this work is on the contiguous multidimensional arrays in C. 521 524 The reason is that programmers are often forced to use the more complex array-of-array form when a contiguous array would be simpler, faster, and safer. … … 524 527 \VRef[Figure]{f:ContiguousNon-contiguous} shows a powerful extension made in C99 for manipulating contiguous \vs non-contiguous arrays.\footnote{C90 also supported non-contiguous arrays.} 525 528 For contiguous-array arguments (including VLA), C99 conjoins one or more of the parameters as a downstream dimension(s), \eg @cols@, implicitly using this parameter to compute the row stride of @m@. 526 There is now sufficient information to support array copying and subscript checking along the columns to prevent changing the argument or buffer-overflow problems, but neither feature is provided.529 There is now sufficient information to support array copying and subscript checking along the columns to prevent changing the argument or buffer-overflow problems, \emph{but neither feature is provided}. 527 530 If the declaration of @fc@ is changed to: 528 531 \begin{cfa} … … 532 535 While this contiguous-array capability is a step forward, it is still the programmer's responsibility to manually manage the number of dimensions and their sizes, both at the function definition and call sites. 533 536 That is, the array does not automatically carry its structure and sizes for use in computing subscripts. 534 While the non-contiguous style in @faa@ looks very similar to @fc@, the compiler only understands the unknown-sized array of row pointers, and it relies on the programmer to traverse the columns in a row correctlywith a correctly bounded loop index.537 While the non-contiguous style in @faa@ looks very similar to @fc@, the compiler only understands the unknown-sized array of row pointers, and it relies on the programmer to traverse the columns in a row with a correctly bounded loop index. 535 538 Specifically, there is no requirement that the rows are the same length, like a poem with different length lines. 536 539 … … 583 586 Again, an array and a point to each of its axes are different. 584 587 \lstinput{28-36}{bkgd-carray-mdim.c} 585 As well, there is pointer decay from each of the matrix axes to pointers, which all havethe same address.588 As well, there is pointer decay from each of the matrix axes to pointers, all having the same address. 586 589 \lstinput{38-44}{bkgd-carray-mdim.c} 587 Finally, subscripting on a @malloc@ result, where the referent may or may not allow subscripting or have the right number of subscripts.590 Finally, subscripting is allowed on a @malloc@ result, where the referent may or may not allow subscripting or have the right number of subscripts. 588 591 589 592 … … 605 608 // caller's perspectives of foo and bar 606 609 \end{cfa} 607 From the caller's perspective, the parameter names (by virtue of being optional) are (useful) comments;608 From the callee's perspective, parameter names are semantically significant.610 From the caller's perspective, the parameter names are semantically optional, but provide useful comments. 611 From the callee's perspective, parameter names are semantically essential. 609 612 Array parameters introduce a further, subtle, semantic difference and considerable freedom to comment. 610 613 611 At the semantic level, there is no such thing as an array parameter, except for one case (@T [static 5]@)discussed shortly.612 Rather, there are only pointer parameters.614 At the semantic level, there is no such thing as an array parameter, except for one case, @T [static 5]@, discussed shortly. 615 Instead, there are only pointer parameters. 613 616 This fact probably shares considerable responsibility for the common sense of \emph{an array is just a pointer}, which has been refuted in non-parameter contexts. 614 617 This fact holds in both the caller's and callee's perspectives. 615 However, a parameter's type can include ``array of'', \eg the type ``pointer to array of 5 ints'' (@T (*)[5]@) is a pointer type.616 This type is fully meaningful in the sense that its description does not contain any information that the type system ignores, and the type appears the same in the caller's \vscallee's perspectives.618 However, a parameter's type can include ``array of'', \eg the type ``pointer to array of 5 ints'' (@T (*)[5]@), which is a pointer type. 619 This type is fully meaningful in the sense that its description does not contain any information that the type system ignores, and the type appears the same in the caller's and callee's perspectives. 617 620 In fact, the outermost type constructor (syntactically first dimension) is really the one that determines the parameter flavour. 618 621 … … 621 624 622 625 \begin{figure} 626 \setlength{\tabcolsep}{7pt} 623 627 \begin{tabular}{@{}llll@{}} 624 628 \begin{cfa} … … 663 667 Yet, C allows array syntax for the outermost type constructor, from which comes the freedom to comment. 664 668 An array parameter declaration can specify the outermost dimension with a dimension value, @[10]@ (which is ignored), an empty dimension list, @[ ]@, or a pointer, @*@, as seen in \VRef[Figure]{f:ArParmEquivDecl}. 665 The rationale for rejecting the first invalid row follows shortly, while the second invalid row is simplenonsense, included to complete the pattern; its syntax hints at what the final row actually achieves.669 The rationale for rejecting the first invalid row follows shortly, while the second invalid row is nonsense, included to complete the pattern; its syntax hints at what the final row actually achieves. 666 670 Note, in the leftmost style, the typechecker ignores the actual value even in a dynamic expression. 667 671 \begin{cfa} … … 674 678 % So are @float[5]*@, @float[]*@ and @float (*)*@. These latter ones are simply nonsense, though they hint at ``1d array of pointers'', whose equivalent syntax options are, @float *[5]@, @float *[]@, and @float **@. 675 679 676 It is a matter of taste as to whether a programmer should use a form as far left as possible (getting the most out of possible subscripting and dimension sizes), sticking to the right (avoiding false comfort from suggesting the typechecker is checking more than it is), or compromising in the middle (reducing unchecked information, yet clearly stating, ``I will subscript'').680 It is a matter of taste as to whether a programmer should use the left form to get the most out of commenting subscripting and dimension sizes, sticking to the right (avoiding false comfort from suggesting the typechecker is checking more than it is), or compromising in the middle (reducing unchecked information, yet clearly stating, ``I will subscript''). 677 681 678 682 Note that this equivalence of pointer and array declarations is special to parameters. … … 680 684 \begin{cfa} 681 685 void f( float * a ) { 682 float * b = a; // ok683 float c[] = a; // reject684 float d[] = { 1.0, 2.0, 3.0 }; // ok686 float * b = a; // ok 687 float c[] = a; // reject 688 float d[] = { 1.0, 2.0, 3.0 }; // ok 685 689 static_assert( sizeof(b) == sizeof(float*) ); 686 690 static_assert( sizeof(d) != sizeof(float*) ); 687 691 } 688 692 \end{cfa} 689 Unfortunately, this equivalence has the consequencethat the type system does not help a caller get it right.693 The consequence of this equivalence is that the type system does not help a caller get it right. 690 694 \begin{cfa} 691 695 float sum( float v[] ); … … 715 719 void foo( int [static @3@] ); 716 720 int ar[@10@]; 717 foo( ar ); // check argument dimension 10 > 3721 foo( ar ); // check argument dimension 10 > 3 718 722 \end{cfa} 719 723 Here, the @static@ storage qualifier defines the minimum array size for its argument. … … 728 732 729 733 With multidimensional arrays, on dimensions after the first, a size is required and, is not ignored. 730 These sizes are required for the callee to be able to subscript.734 These sizes (strides) are required for the callee to be able to subscript. 731 735 \begin{cfa} 732 736 void f( float a[][10], float b[][100] ) { … … 739 743 The significance of an inner dimension's length is a fact of the callee's perspective. 740 744 In the caller's perspective, the type system is quite lax. 741 Here, there is (some, but) little checking that what is being passed, matches.745 Here, there is (some, but) little checking of what is being passed matches the parameter. 742 746 % void f( float [][10] ); 743 747 % int n = 100; … … 774 778 void foo( float a[][10] ) { ... } $\C{// definition}$ 775 779 \end{cfa} 776 Repeating it with the full context of a VLA is useful :780 Repeating it with the full context of a VLA is useful. 777 781 \begin{cfa} 778 782 void foo( int, float [][@*@] ); $\C{// declaration}$ … … 794 798 typedef long int jmp_buf[8]; 795 799 \end{cfa} 796 A instance of this array can be declared as a structure field.800 An instance of this array can be declared as a structure field. 797 801 \begin{cfa} 798 802 struct Jmp_Buf { … … 819 823 Since the data is opaque, list structures are often polymorphic over the data, which is often homogeneous. 820 824 821 The links organize nodes into a particular format, \eg queue, tree, hash table, \etc, with operations specific to that format.825 The links organize nodes into a particular kind of data structure, \eg queue, tree, hash table, \etc, with operations specific to that kind. 822 826 Because a node's existence is independent of the data structure that organizes it, all nodes are manipulated by address not value; 823 827 hence, all data structure routines take and return pointers to nodes and not the nodes themselves. … … 828 832 829 833 This thesis focuses on a reduced design space for linked lists that target \emph{system programmers}. 830 Within this restricted space, all design-issue discussions assume the following invariants; 831 alternatives to the assumptions are discussed under Future Work (\VRef{toc:lst:futwork}). 834 Within this restricted space, all design-issue discussions assume the following invariants. 832 835 \begin{itemize} 833 836 \item A doubly-linked list is being designed. … … 835 838 Circular \vs ordered linking is discussed under List identity (\VRef{toc:lst:issue:ident}). 836 839 \item Link fields are system-managed. 840 The system has freedom over how to represent these links. 837 841 The user works with the system-provided API to query and modify list membership. 838 The system has freedom over how to represent these links.839 842 \item The user data must provide storage for the list link-fields. 840 843 Hence, a list node is \emph{statically} defined as data and links \vs a node that is \emph{dynamically} constructed from data and links \see{\VRef{toc:lst:issue:attach}}. 841 844 \end{itemize} 845 Alternatives to these assumptions are discussed under Future Work (\VRef{toc:lst:futwork}). 842 846 843 847 … … 845 849 \label{s:PreexistingLinked-ListLibraries} 846 850 847 Two preexisting linked-list libraries are used throughout, to show examples of the concepts being defined, 848 and further libraries are introduced as needed. 851 To show examples of the concepts being defined, two preexisting linked-list libraries are used throughout and further libraries are introduced as needed. 849 852 \begin{enumerate} 850 853 \item Linux Queue library~\cite{lst:linuxq} (LQ) of @<sys/queue.h>@. … … 852 855 \end{enumerate} 853 856 %A general comparison of libraries' abilities is given under Related Work (\VRef{toc:lst:relwork}). 854 For the discussion, assume the fictionaltype @req@ (request) is the user's payload in examples.855 As well, the list library is helping the user manage (organize) requests, \eg a request can be work on the level of handling a network arrival-event or scheduling a thread.857 For the discussion, assume the type @req@ (request) is the user's payload in examples. 858 Then the job of a list library is to help a user manage (organize) requests, \eg a request can be a network arrival-event processed by a web browser or a thread blocked/scheduled by the runtime. 856 859 857 860 … … 866 869 The wrapped style distinguishes between wrapping a reference and wrapping a value, \eg @list<req *>@ or @list<req>@. 867 870 (For this discussion, @list<req &>@ is similar to @list<req *>@.) 868 This difference is one of user style , not framework capability.871 This difference is one of user style and performance (copying), not framework capability. 869 872 Library LQ is intrusive; STL is wrapped with reference and value. 870 873 … … 973 976 An example of an attribute on the link fields is cache alignment, possibly in conjunction with other @req@ fields, improving locality and/or avoiding false sharing. 974 977 For example, if a list is frequently traversed in the forward direction, and infrequently gets elements removed at random positions, then an ideal layout for cache locality puts the forward links, together with frequently-used payload data on one cache line, leaving the reverse links on a colder cache line. 975 Supplying thelink fields by inheritance makes them implicit and relies on compiler placement, such as the start or end of @req@, and no explicit attributes.978 In contrast, supplying link fields by inheritance makes them implicit and relies on compiler placement, such as the start or end of @req@, and no explicit attributes. 976 979 Wrapped reference has no control over the link fields, but the separate data allows some control; 977 980 wrapped value has no control over data or links. 978 981 979 982 Another subtle advantage of intrusive arrangement is that a reference to a user-level item (@req@) is sufficient to navigate or manage the item's membership. 980 In LQ, the intrusive @req@ pointer is the right argument type for operations @LIST_NEXT@ or @LIST_REMOVE@;983 In LQ, the intrusive @req@ pointer is the correct argument type for operations @LIST_NEXT@ or @LIST_REMOVE@; 981 984 there is no distinguishing a @req@ from a @req@ in a list. 982 985 The same is not true of STL, wrapped reference or value. … … 989 992 Then, a novel use can put a @req@ in a list, without requiring any upstream change in the @req@ library. 990 993 In intrusive, the ability to be listed must be planned during the definition of @req@. 994 Optimistically adding a couple links for future use is normally cheap because links are small and memory is big. 991 995 992 996 \begin{figure} … … 1014 1018 An intrusive-primitive library like LQ lets users choose when to make this tradeoff. 1015 1019 A wrapped-primitive library like STL forces users to incur the costs of wrapping, whether or not they access its benefits. 1016 \CFA is capable of supporting a wrapped library, if need arose.1020 Like LQ, \CFA is capable of supporting a wrapped library, if need arose. 1017 1021 1018 1022 … … 1145 1149 \subsection{User Integration: Preprocessed \vs Type-System Mediated} 1146 1150 1147 While the syntax for LQ is reasonably succinct, it comes at the cost of using C preprocessor macros for generics, which are not part of the language type-system, like \CC templates.1151 While the syntax for LQ is reasonably succinct, it comes at the cost of using C preprocessor macros for generics, which are not part of the language type-system, unlike \CC templates. 1148 1152 Hence, small errors in macro arguments can lead to large substitution mistakes, as the arguments maybe textually written in many places and/or concatenated with other arguments/text to create new names and expressions. 1149 This can lead to a cascade of error messages that are confusing and difficult to debug. 1150 For example, argument errors like @a.b,c@, comma instead of period, or @by-pri@, minus instead of underscore, can produce many error messages. 1151 1152 Instead, language function calls (even with inlining) handled argument mistakes locally at the call, giving very specific error message. 1153 \CC @concepts@ were introduced in @templates@ to deal with just this problem. 1153 Hence, textual expansion can lead to a cascade of error messages that are confusing and difficult to debug. 1154 For example, argument errors like @a.b@{\Large\color{red},}@c@, comma instead of period, or @by@{\Large\color{red}-}@pri@, minus instead of underscore, can produce many error messages. 1155 Note, similar problems exist for \CC templates. 1156 1157 Instead, language function calls (even with inlining) handle argument mistakes locally at the call, giving very specific error message. 1158 \CC @concepts@ were introduced in @templates@ to deal with this problem. 1154 1159 1155 1160 % example of poor error message due to LQ's preprocessed integration … … 1166 1171 All examples so far use two distinct types for: 1167 1172 an item found in a list (type @req@ of variable @r1@, see \VRef[Figure]{fig:lst-issues-attach}), and the list (type @reql@ of variable @reqs_pri@, see \VRef[Figure]{fig:lst-issues-ident}). 1168 This kind of list is ``headed'', where the empty list is just a head.1169 An alternate ``ad-hoc''approach omits the header, where the empty list is no nodes.1173 This kind of list is \newterm{headed}, where the empty list is just a head. 1174 An alternate ad-hoc approach omits the header, where the empty list is no nodes. 1170 1175 Here, a pointer to any node can traverse its link fields: right or left and around, depending on the data structure. 1171 1176 Note, a headed list is superset of an ad-hoc list, and can normally perform all of the ad-hoc operations. … … 1202 1207 Note, a list does not need to use links to denote its size; 1203 1208 it can use a node counter in the header, where $N$ node traversals indicates complete navigation of the list. 1204 However, managing the number of nodes is an additional cost, as the links must always be managed.1209 However, managing the number of nodes is an additional cost, whereas the links must always be managed. 1205 1210 1206 1211 The following discussion refers to the LQ representations, detailed in \VRef[Figure]{fig:lst-issues-end}, using a null pointer to mark end points. … … 1251 1256 1252 1257 A C character constant is an ASCII/Latin-1 character enclosed in single-quotes, \eg @'x'@, @'@\textsterling@'@. 1253 A wide C character constant is the same, except prefixed by the letter @L@, @u@, or @U@, \eg @u'\u25A0'@ (black square), where the @ \u@ identifies a universal character name.1254 A character can be formed from an escape sequence, which expresses a non-typable character @'\f'@ form feed, a delimiter character @'\''@ embedded single quote, or a raw character @'\xa3'@\textsterling.1258 A wide C character constant is the same, except prefixed by the letter @L@, @u@, or @U@, \eg @u'\u25A0'@ (black square), where the @'\u'@ identifies a universal character name. 1259 A character can be formed from an escape sequence, which expresses a non-typable character @'\f'@, form feed, a delimiter character @'\''@, embedded single quote, or a raw character @'\xa3'@, \textsterling. 1255 1260 1256 1261 A C character string is zero or more regular, wide, or escape characters enclosed in double-quotes @"xyz\n"@. 1257 The kind of characters in the string is denoted by a prefix: UTF-8 characters are prefixed by @u8@, wide characters are prefixed by @L@, @u@, or @U@. 1258 1259 For UTF-8 string literals, the array elements have type @char@ and are initialized with the characters of the multi-byte character sequences, \eg @u8"\xe1\x90\x87"@ (Canadian syllabic Y-Cree OO). 1262 The kind of characters in the string is denoted by a prefix: wide characters are prefixed by @L@, @u@, or @U@; UTF-8 characters are prefixed by @u8@. 1263 1260 1264 For wide string literals prefixed by the letter @L@, the array elements have type @wchar_t@ and are initialized with the wide characters corresponding to the multi-byte character sequence, \eg @L"abc@$\mu$@"@ and are read/printed using @wscanf@/@wprintf@. 1261 The value of a wide-character is implementation -defined, usually a UTF-16 character.1265 The value of a wide-character is implementation defined, usually a UTF-16 character. 1262 1266 For wide string literals prefixed by the letter @u@ or @U@, the array elements have type @char16_t@ or @char32_t@, respectively, and are initialized with wide characters corresponding to the multi-byte character sequence, \eg @u"abc@$\mu$@"@, @U"abc@$\mu$@"@. 1263 1267 The value of a @"u"@ character is an UTF-16 character; 1264 1268 the value of a @"U"@ character is an UTF-32 character. 1265 The value of a string literal containing a multi-byte character or escape sequence not represented in the execution character set is implementation-defined. 1269 The value of a string literal containing a multi-byte character or escape sequence not represented in the execution character set is implementation defined. 1270 For UTF-8 string literals, the array elements have type @char@ and are initialized with the characters of the multi-byte character sequences, \eg @u8"\xe1\x90\x87"@ (Canadian syllabic Y-Cree OO). 1266 1271 1267 1272 C strings are null-terminated rather than maintaining a separate string length. … … 1273 1278 This property is only preserved by the compiler with respect to character constants, \eg @"abc"@ is actually @"abc\0"@, \ie 4 characters rather than 3. 1274 1279 Otherwise, the compiler does not participate, making string operations both unsafe and inefficient. 1275 For example, it is common in C to: forget that a character constant is larger than it appears during manipulation, that extra storage is needed in a character array for the terminator, or that the terminator must be preserved during string operations, otherwise there are array overruns. 1280 For example, it is common in C to: 1281 \begin{itemize} 1282 \item 1283 forget that a character constant is larger than it appears during manipulation, 1284 \item 1285 that extra storage is needed in a character array for the terminator, 1286 \item 1287 or that the terminator must be preserved during string operations, otherwise there are array overruns. 1288 \end{itemize} 1276 1289 Finally, the need to repeatedly scan an entire string to determine its length can result in significant cost, as it is impossible to cache the length in many cases, \eg when a string is passed into another function. 1277 1290 -
doc/theses/mike_brooks_MMath/programs/bkgd-c-tyerr.c
r79ec8c3 rf2b74e3 16 16 17 17 float pi = 3.14; 18 void f( void (*g)(void) ) { g(); }18 void f( void (*g)(void) ); 19 19 @f( &pi );@ $\C{// wrong}$ 20 20 } -
doc/theses/mike_brooks_MMath/programs/bkgd-carray-decay.c
r79ec8c3 rf2b74e3 10 10 assert( sizeof(pa0x) != sizeof(ar) ); 11 11 12 void f( float x[10], float * y) {12 void f( @float x[10]@, @float * y@ ) { 13 13 static_assert( sizeof(x) == sizeof(void *) ); 14 14 static_assert( sizeof(y) == sizeof(void *) ); … … 16 16 f( 0, 0 ); 17 17 18 // reusing local var `float a[10];`}18 // reusing local variable float ar[10] 19 19 float v; 20 20 f( ar, ar ); $\C{// ok: two decays, one into an array spelling}$ -
doc/theses/mike_brooks_MMath/programs/bkgd-carray-mdim.c
r79ec8c3 rf2b74e3 38 38 // float (*b[3])[10]; 39 39 float * b[3]; 40 for ( int i = 0; i < 3; i ++) {41 b[i] = malloc( sizeof(float[10]));40 for ( int i = 0; i < 3; i ++ ) { 41 b[i] = malloc( sizeof( float[10] ) ); 42 42 } 43 43 mx[2][3]; -
doc/theses/mike_brooks_MMath/programs/lst-issues-multi-static.run.c
r79ec8c3 rf2b74e3 20 20 struct req { 21 21 int pri, rqr; 22 LIST_ENTRY( req) by_pri;23 LIST_ENTRY( req) by_rqr;22 LIST_ENTRY( req ) by_pri; 23 LIST_ENTRY( req ) by_rqr; 24 24 }; 25 25 26 LIST_HEAD( reql, req);26 LIST_HEAD( reql, req ); 27 27 28 28 struct reql reqs_pri; … … 31 31 struct reql reqs_rqr_99; 32 32 33 LIST_INIT( &reqs_pri);34 LIST_INIT( &reqs_rqr_42);35 LIST_INIT( &reqs_rqr_17);36 LIST_INIT( &reqs_rqr_99);33 LIST_INIT( &reqs_pri ); 34 LIST_INIT( &reqs_rqr_42 ); 35 LIST_INIT( &reqs_rqr_17 ); 36 LIST_INIT( &reqs_rqr_99 ); 37 37 38 38 struct req … … 44 44 r99a = {3, 99}; 45 45 46 LIST_INSERT_HEAD( &reqs_pri, &r17c, by_pri);47 LIST_INSERT_HEAD( &reqs_pri, &r99a, by_pri);48 LIST_INSERT_HEAD( &reqs_pri, &r17b, by_pri);49 LIST_INSERT_HEAD( &reqs_pri, &r42b, by_pri);50 LIST_INSERT_HEAD( &reqs_pri, &r17a, by_pri);51 LIST_INSERT_HEAD( &reqs_pri, &r42a, by_pri);46 LIST_INSERT_HEAD( &reqs_pri, &r17c, by_pri ); 47 LIST_INSERT_HEAD( &reqs_pri, &r99a, by_pri ); 48 LIST_INSERT_HEAD( &reqs_pri, &r17b, by_pri ); 49 LIST_INSERT_HEAD( &reqs_pri, &r42b, by_pri ); 50 LIST_INSERT_HEAD( &reqs_pri, &r17a, by_pri ); 51 LIST_INSERT_HEAD( &reqs_pri, &r42a, by_pri ); 52 52 53 LIST_INSERT_HEAD( &reqs_rqr_42, &r42b, by_rqr);54 LIST_INSERT_HEAD( &reqs_rqr_42, &r42a, by_rqr);53 LIST_INSERT_HEAD( &reqs_rqr_42, &r42b, by_rqr ); 54 LIST_INSERT_HEAD( &reqs_rqr_42, &r42a, by_rqr ); 55 55 56 LIST_INSERT_HEAD( &reqs_rqr_17, &r17c, by_rqr);57 LIST_INSERT_HEAD( &reqs_rqr_17, &r17b, by_rqr);58 LIST_INSERT_HEAD( &reqs_rqr_17, &r17a, by_rqr);56 LIST_INSERT_HEAD( &reqs_rqr_17, &r17c, by_rqr ); 57 LIST_INSERT_HEAD( &reqs_rqr_17, &r17b, by_rqr ); 58 LIST_INSERT_HEAD( &reqs_rqr_17, &r17a, by_rqr ); 59 59 60 LIST_INSERT_HEAD( &reqs_rqr_99, &r99a, by_rqr);60 LIST_INSERT_HEAD( &reqs_rqr_99, &r99a, by_rqr ); 61 61 62 62 … … 67 67 68 68 struct req *cur; 69 LIST_FOREACH( cur, &reqs_pri, by_pri)70 printf( "{%d %d} ", cur->pri, cur->rqr);71 printf( "| ");72 LIST_FOREACH( cur, &reqs_rqr_42, by_rqr)73 printf( "{%d %d} ", cur->pri, cur->rqr);74 printf( "| ");75 LIST_FOREACH( cur, &reqs_rqr_17, by_rqr)76 printf( "{%d %d} ", cur->pri, cur->rqr);77 printf( "| ");78 LIST_FOREACH( cur, &reqs_rqr_99, by_rqr)79 printf( "{%d %d} ", cur->pri, cur->rqr);80 printf( "\n");69 LIST_FOREACH( cur, &reqs_pri, by_pri ) 70 printf( "{%d %d} ", cur->pri, cur->rqr ); 71 printf( "| " ); 72 LIST_FOREACH( cur, &reqs_rqr_42, by_rqr ) 73 printf( "{%d %d} ", cur->pri, cur->rqr ); 74 printf( "| " ); 75 LIST_FOREACH( cur, &reqs_rqr_17, by_rqr ) 76 printf( "{%d %d} ", cur->pri, cur->rqr ); 77 printf( "| " ); 78 LIST_FOREACH( cur, &reqs_rqr_99, by_rqr ) 79 printf( "{%d %d} ", cur->pri, cur->rqr ); 80 printf( "\n" ); 81 81 82 82 }
Note:
See TracChangeset
for help on using the changeset viewer.