Changeset 8614140


Ignore:
Timestamp:
Jan 8, 2026, 1:26:42 PM (4 weeks ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
master
Children:
fb7c9168
Parents:
79ba50c (diff), 4904b05 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
9 added
3 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/mike_brooks_MMath/Makefile

    r79ba50c r8614140  
    1111BibRep = ../../bibliography
    1212
     13strip-top-dir = $(foreach p,$1,$(patsubst %/,%,$(subst $(firstword $(subst /, ,$(p)))/,, $(p))))
     14
     15.SUFFIXES:  # disable make built-in rules
     16
    1317TeXSRC = ${wildcard *.tex}
    1418PicSRC = ${notdir ${wildcard ${Pictures}/*.png}} ${notdir ${wildcard ${Pictures}/*.fig}}
     
    1923PgmSRC = ${notdir ${wildcard ${Programs}/*}}
    2024RunPgmSRC = ${notdir ${wildcard ${Programs}/*.run.*}}
     25NondemoPgmSRC = ${call strip-top-dir,${wildcard ${Programs}/*/*.c*}}
    2126BibSRC = ${wildcard *.bib}
    2227
     
    5762# File Dependencies
    5863
    59 ${DOCUMENT}: ${TeXSRC} $(RunPgmOut) ${DemoPgmOut} ${PlotSRC} ${PicSRC} ${BibSRC} ${BibRep}/pl.bib ${LaTMac}/common.tex Makefile | ${Build}
     64${DOCUMENT}: ${TeXSRC} $(RunPgmOut) ${DemoPgmOut} ${NondemoPgmSRC} ${PlotSRC} ${PicSRC} ${BibSRC} ${BibRep}/pl.bib ${LaTMac}/common.tex Makefile | ${Build}
    6065        echo ${PicSRC}
    6166        echo ${GraphSRC_OLD}
  • doc/theses/mike_brooks_MMath/array.tex

    r79ba50c r8614140  
    22\label{c:Array}
    33
    4 Arrays in C are possibly the single most misunderstood and incorrectly used feature in the language, resulting in the largest proportion of runtime errors and security violations.
     4Arrays in C are possibly the single most misunderstood and incorrectly used feature in the language \see{\VRef{s:Array}}, resulting in the largest proportion of runtime errors and security violations.
    55This chapter describes the new \CFA language and library features that introduce a length-checked array type, @array@, to the \CFA standard library~\cite{Cforall}.
    66
     
    1313\label{s:ArrayIntro}
    1414
    15 The new \CFA array is declared by instantiating the generic @array@ type,
    16 much like instantiating any other standard-library generic type (such as \CC @vector@),
    17 though using a new style of generic parameter.
     15The new \CFA array is declared by instantiating the generic @array@ type, much like instantiating any other standard-library generic type (such as \CC @vector@), using a new style of generic parameter.
    1816\begin{cfa}
    1917@array( float, 99 )@ x;                                 $\C[2.5in]{// x contains 99 floats}$
     
    2422void f( @array( float, 42 )@ & p ) {}   $\C{// p accepts 42 floats}$
    2523f( x );                                                                 $\C{// statically rejected: type lengths are different, 99 != 42}$
     24
    2625test2.cfa:3:1 error: Invalid application of existing declaration(s) in expression.
    2726Applying untyped:  Name: f ... to:  Name: x
     
    3736g( x, 0 );                                                              $\C{// T is float, N is 99, dynamic subscript check succeeds}$
    3837g( x, 1000 );                                                   $\C{// T is float, N is 99, dynamic subscript check fails}$
     38
    3939Cforall Runtime error: subscript 1000 exceeds dimension range [0,99) $for$ array 0x555555558020.
    4040\end{cfa}
     
    9292is a sufficient postcondition.
    9393In an imperative language like C and \CFA, it is also necessary to discuss side effects, for which an even heavier formalism, like separation logic, is required.
    94 Secondly, TODO: bash Rust.
    95 % TODO: cite the crap out of these claims.
     94Secondly: ... bash Rust.
     95... cite the crap out of these claims.
    9696\end{comment}
    9797
     
    110110forall( T & | sized(T) )
    111111T * alloc() {
    112         return @(T *)@malloc( @sizeof(T)@ );
     112        return @(T *)@malloc( @sizeof(T)@ );    // C malloc
    113113}
    114114\end{cfa}
     
    132132The loops follow the familiar pattern of using the variable @dim@ to iterate through the arrays.
    133133Most importantly, the type system implicitly captures @dim@ at the call of @f@ and makes it available throughout @f@ as @N@.
    134 The example shows @dim@ adapting into a type-system managed length at the declarations of @x@, @y@, and @result@, @N@ adapting in the same way at @f@'s loop bound, and a pass-thru use of @dim@ at @f@'s declaration of @ret@.
     134The example shows @dim@ adapting into a type-system managed length at the declarations of @x@, @y@, and @result@; @N@ adapting in the same way at @f@'s loop bound; and a pass-thru use of @dim@ at @f@'s declaration of @ret@.
    135135Except for the lifetime-management issue of @result@, \ie explicit @free@, this program has eliminated both the syntactic and semantic problems associated with C arrays and their usage.
    136136The result is a significant improvement in safety and usability.
     
    148148\end{itemize}
    149149
    150 \VRef[Figure]{f:TemplateVsGenericType} shows @N@ is not the same as a @size_t@ declaration in a \CC \lstinline[language=C++]{template}.
     150\VRef[Figure]{f:TemplateVsGenericType} shows @N@ is not the same as a @size_t@ declaration in a \CC \lstinline[language=C++]{template}.\footnote{
     151The \CFA program requires a snapshot declaration for \lstinline{n} to compile, as described at the end of \Vref{s:ArrayTypingC}.}
    151152\begin{enumerate}[leftmargin=*]
    152153\item
    153154The \CC template @N@ can only be a compile-time value, while the \CFA @N@ may be a runtime value.
    154155\item
    155 \CC does not allow a template function to be nested, while \CFA lets its polymorphic functions to be nested.
     156\CC does not allow a template function to be nested, while \CFA allows polymorphic functions be nested.
    156157Hence, \CC precludes a simple form of information hiding.
    157158\item
     
    176177% mycode/arrr/thesis-examples/check-peter/cs-cpp.cpp, v10
    177178\end{enumerate}
    178 The \CC template @array@ type mitigates points \VRef[]{p:DimensionPassing} and \VRef[]{p:ArrayCopy}, but it is also trying to accomplish a similar mechanism to \CFA @array@.
     179The \CC template @std::array@ tries to accomplish a similar mechanism to \CFA @array@.
     180It is an aggregate type with the same semantics as a @struct@ holding a C-style array \see{\VRef{s:ArraysCouldbeValues}}, which mitigates points \VRef[]{p:DimensionPassing} and \VRef[]{p:ArrayCopy}.
    179181
    180182\begin{figure}
    181 \begin{tabular}{@{}l@{\hspace{20pt}}l@{}}
     183\begin{tabular}{@{}ll@{}}
    182184\begin{c++}
    183185
     
    187189}
    188190int main() {
    189 
    190         int ret[10], x[10];
    191         for ( int i = 0; i < 10; i += 1 ) x[i] = i;
    192         @copy<int, 10 >( ret, x );@
    193         for ( int i = 0; i < 10; i += 1 )
     191        const size_t  n = 10;   // must be constant
     192        int ret[n], x[n];
     193        for ( int i = 0; i < n; i += 1 ) x[i] = i;
     194        @copy<int, n >( ret, x );@
     195        for ( int i = 0; i < n; i += 1 )
    194196                cout << ret[i] << ' ';
    195197        cout << endl;
     
    203205                for ( i; N ) ret[i] = x[i];
    204206        }
    205 
    206         const int n = promptForLength();
     207        size_t  n;
     208        sin | n;
    207209        array( int, n ) ret, x;
    208210        for ( i; n ) x[i] = i;
     
    228230When the argument lengths themselves are statically unknown,
    229231the static check is conservative and, as always, \CFA's casting lets the programmer use knowledge not shared with the type system.
    230 \begin{tabular}{@{\hspace{0.5in}}l@{\hspace{1in}}l@{}}
    231 \lstinput{90-97}{hello-array.cfa}
    232 &
    233 \lstinput{110-117}{hello-array.cfa}
    234 \end{tabular}
    235 
    236 \noindent
    237 This static check's full rules are presented in \VRef[Section]{s:ArrayTypingC}.
     232\lstinput{90-96}{hello-array.cfa}
     233This static check's rules are presented in \VRef[Section]{s:ArrayTypingC}.
    238234
    239235Orthogonally, the \CFA array type works within generic \emph{types}, \ie @forall@-on-@struct@.
    240236The same argument safety and the associated implicit communication of array length occurs.
    241237Preexisting \CFA allowed aggregate types to be generalized with type parameters, enabling parameterizing of element types.
    242 This has been extended to allow parameterizing by dimension.
    243 Doing so gives a refinement of C's ``flexible array member''~\cite[\S~6.7.2.1.18]{C11}.
     238This feature is extended to allow parameterizing by dimension.
     239Doing so gives a refinement of C's ``flexible array member''~\cite[\S~6.7.2.1.18]{C11}:
    244240\begin{cfa}
    245241struct S {
     
    264260\end{cfa}
    265261This ability to avoid casting and size arithmetic improves safety and usability over C flexible array members.
    266 Finally, inputs and outputs are given at the bottom for different sized schools.
     262Finally, inputs and outputs are given on the right for different sized schools.
    267263The example program prints the courses in each student's preferred order, all using the looked-up display names.
    268264
    269265\begin{figure}
    270 \begin{cquote}
    271 \lstinput{50-55}{hello-accordion.cfa}
     266\begin{lrbox}{\myboxA}
     267\begin{tabular}{@{}l@{}}
     268\lstinput{50-55}{hello-accordion.cfa} \\
    272269\lstinput{90-98}{hello-accordion.cfa}
    273 \ \\
    274 @$ cat school1@
    275 \lstinput{}{school1}
    276 
    277 @$ ./a.out < school1@
    278 \lstinput{}{school1.out}
    279 
    280 @$ cat school2@
    281 \lstinput{}{school2}
    282 
    283 @$ ./a.out < school2@
    284 \lstinput{}{school2.out}
    285 \end{cquote}
     270\end{tabular}
     271\end{lrbox}
     272
     273\begin{lrbox}{\myboxB}
     274\begin{tabular}{@{}l@{}}
     275@$ cat school1@ \\
     276\lstinputlisting{school1} \\
     277@$ ./a.out < school1@ \\
     278\lstinputlisting{school1.out} \\
     279@$ cat school2@ \\
     280\lstinputlisting{school2} \\
     281@$ ./a.out < school2@ \\
     282\lstinputlisting{school2.out}
     283\end{tabular}
     284\end{lrbox}
     285
     286\setlength{\tabcolsep}{10pt}
     287\begin{tabular}{@{}ll@{}}
     288\usebox\myboxA
     289&
     290\usebox\myboxB
     291\end{tabular}
    286292
    287293\caption{\lstinline{School} Example, Input and Output}
     
    290296
    291297When a function operates on a @School@ structure, the type system handles its memory layout transparently.
    292 \lstinput{30-37}{hello-accordion.cfa}
     298\lstinput{30-36}{hello-accordion.cfa}
    293299In the example, function @getPref@ returns, for the student at position @is@, what is the position of their @pref@\textsuperscript{th}-favoured class?
    294300
     
    296302\section{Dimension Parameter Implementation}
    297303
    298 The core of the preexisting \CFA compiler already had the ``heavy equipment'' needed to provide the feature set just reviewed (up to bugs in cases not yet exercised).
     304The core of the preexisting \CFA compiler already has the ``heavy equipment'' needed to provide the feature set just reviewed (up to bugs in cases not yet exercised).
    299305To apply this equipment in tracking array lengths, I encoded a dimension (array's length) as a type.
    300306The type in question does not describe any data that the program actually uses at runtime.
     
    323329\begin{itemize}[leftmargin=*]
    324330\item
    325         Resolver provided values for a used declaration's type-system variables, gathered from type information in scope at the usage site.
    326 \item
    327         The box pass, encoding information about type parameters into ``extra'' regular parameters/arguments on declarations and calls.
     331        Resolver provided values for a declaration's type-system variables, gathered from type information in scope at the usage site.
     332\item
     333        The box pass, encoding information about type parameters into ``extra'' regular parameters and arguments on declarations and calls.
    328334        Notably, it conveys the size of a type @foo@ as a @__sizeof_foo@ parameter, and rewrites the @sizeof(foo)@ expression as @__sizeof_foo@, \ie a use of the parameter.
    329335\end{itemize}
     
    331337The rules for resolution had to be restricted slightly, in order to achieve important refusal cases.
    332338This work is detailed in \VRef[Section]{s:ArrayTypingC}.
    333 However, the resolution--boxing scheme, in its preexisting state, was already equipped to work on (desugared) dimension parameters.
     339However, the resolution--boxing scheme, in its preexisting state, is equipped to work on (desugared) dimension parameters.
    334340The following discussion explains the desugaring and how correctly lowered code results.
    335341
     
    357363\end{enumerate}
    358364The chosen solution is to encode the value @N@ \emph{as a type}, so items 1 and 2 are immediately available for free.
    359 Item 3 needs a way to recover the encoded value from a (valid) type (and to reject invalid types occurring here).
     365Item 3 needs a way to recover the encoded value from a (valid) type and to reject invalid types.
    360366Item 4 needs a way to produce a type that encodes the given value.
    361367
     
    416422        The type @thing(N)@ is (replaced by @void *@, but thereby effectively) gone.
    417423\item
    418         The @sout...@ expression (being an application of the @?|?@ operator) has a regular variable (parameter) usage for its second argument.
     424        The @sout...@ expression has a regular variable (parameter) usage for its second argument.
    419425\item
    420426        Information about the particular @thing@ instantiation (value 10) is moved, from the type, to a regular function-call argument.
     
    455461\begin{cfa}
    456462enum { n = 42 };
    457 float x[@n@];   // or just 42
    458 float (*xp1)[@42@] = &x;    // accept
    459 float (*xp2)[@999@] = &x;   // reject
     463float x[@n@];   $\C{// or just 42}$
     464float (*xp1)[@42@] = &x;    $\C{// accept}$
     465float (*xp2)[@999@] = &x;   $\C{// reject}$
    460466warning: initialization of 'float (*)[999]' from incompatible pointer type 'float (*)[42]'
    461467\end{cfa}
    462468When a variable is involved, C and \CFA take two different approaches.
    463 Today's C compilers accept the following without warning.
     469Today's C compilers accept the following without a warning.
    464470\begin{cfa}
    465471static const int n = 42;
     
    482488The way the \CFA array is implemented, the type analysis for this case reduces to a case similar to the earlier C version.
    483489The \CFA compiler's compatibility analysis proceeds as:
    484 \begin{itemize}[parsep=0pt]
     490\begin{itemize}[leftmargin=*,parsep=0pt]
    485491\item
    486492        Is @array( float, 999 )@ type-compatible with @array( float, n )@?
     
    510516        in order to preserve the length information that powers runtime bound-checking.}
    511517Therefore, the need to upgrade legacy C code is low.
    512 Finally, if this incompatibility is a problem onboarding C programs to \CFA, it is should be possible to change the C type check to a warning rather than an error, acting as a \emph{lint} of the original code for a missing type annotation.
     518Finally, if this incompatibility is a problem onboarding C programs to \CFA, it should be possible to change the C type check to a warning rather than an error, acting as a \emph{lint} of the original code for a missing type annotation.
    513519
    514520To handle two occurrences of the same variable, more information is needed, \eg, this is fine,
     
    516522int n = 42;
    517523float x[@n@];
    518 float (*xp)[@n@] = x;   // accept
     524float (*xp)[@n@] = x;   $\C{// accept}$
    519525\end{cfa}
    520526where @n@ remains fixed across a contiguous declaration context.
    521 However, intervening dynamic statement cause failures.
     527However, intervening dynamic statements can cause failures.
    522528\begin{cfa}
    523529int n = 42;
    524530float x[@n@];
    525 @n@ = 999; // dynamic change
    526 float (*xp)[@n@] = x;   // reject
    527 \end{cfa}
    528 However, side-effects can occur in a contiguous declaration context.
     531@n@ = 999; $\C{// dynamic change}$
     532float (*xp)[@n@] = x;   $\C{// reject}$
     533\end{cfa}
     534As well, side-effects can even occur in a contiguous declaration context.
    529535\begin{cquote}
    530536\setlength{\tabcolsep}{20pt}
     
    536542void f() {
    537543        float x[@n@] = { g() };
    538         float (*xp)[@n@] = x;   // reject
     544        float (*xp)[@n@] = x;                   // reject
    539545}
    540546\end{cfa}
     
    544550int @n@ = 42;
    545551void g() {
    546         @n@ = 99;
     552        @n@ = 999;              // accept
    547553}
    548554
     
    553559The issue here is that knowledge needed to make a correct decision is hidden by separate compilation.
    554560Even within a translation unit, static analysis might not be able to provide all the information.
    555 However, if the example uses @const@, the check is possible.
     561However, if the example uses @const@, the check is possible even though the value is unknown.
    556562\begin{cquote}
    557563\setlength{\tabcolsep}{20pt}
     
    563569void f() {
    564570        float x[n] = { g() };
    565         float (*xp)[n] = x;   // reject
     571        float (*xp)[n] = x;             // accept
    566572}
    567573\end{cfa}
     
    571577@const@ int n = 42;
    572578void g() {
    573         @n = 99@; // allowed
     579        @n = 999@;              // reject
    574580}
    575581
     
    692698An expression-compatibility question is a new addition to the \CFA compiler, and occurs in the context of dimension expressions, and possibly enumerations assigns, which must be unique.
    693699
    694 % TODO: ensure these compiler implementation matters are treated under \CFA compiler background: type unification, cost calculation, GenPoly.
     700% ... ensure these compiler implementation matters are treated under \CFA compiler background: type unification, cost calculation, GenPoly.
    695701
    696702The relevant technical component of the \CFA compiler is the standard type-unification within the type resolver.
     
    726732\end{cfa}
    727733when resolving a function call to @g@, the first unification stage compares the type @T@ of the parameter with @array( float, n + 1 )@, of the argument.
    728 \PAB{TODO: finish.}
    729734
    730735The actual rules for comparing two dimension expressions are conservative.
     
    732737is to imply, ``all else being equal, allow an array with length calculated by $e_1$
    733738to be passed to a function expecting a length-$e_2$ array.''\footnote{
    734         TODO: Deal with directionality, that I'm doing exact-match, no ``at least as long as,'' no subtyping.
     739        ... Deal with directionality, that I'm doing exact-match, no ``at least as long as,'' no subtyping.
    735740        Should it be an earlier scoping principle?  Feels like it should matter in more places than here.}
    736741So, a ``yes'' answer must represent a guarantee that both expressions evaluate the
     
    746751So, a variable and a literal can never match.
    747752
    748 TODO: Discuss the interaction of this dimension hoisting with the challenge of extra unification for cost calculation
     753... Discuss the interaction of this dimension hoisting with the challenge of extra unification for cost calculation
    749754\end{comment}
    750755
    751 The conservatism of the new rule set can leave a programmer needing a recourse, when needing to use a dimension expression whose stability argument is more subtle than current-state analysis.
     756The conservatism of the new rule set can leave a programmer requiring a recourse, when needing to use a dimension expression whose stability argument is more subtle than current-state analysis.
    752757This recourse is to declare an explicit constant for the dimension value.
    753758Consider these two dimension expressions, whose uses are rejected by the blunt current-state rules:
     
    755760void f( int @&@ nr, @const@ int nv ) {
    756761        float x[@nr@];
    757         float (*xp)[@nr@] = &x;   // reject: nr varying (no references)
     762        float (*xp)[@nr@] = &x;                 // reject: nr varying (no references)
    758763        float y[@nv + 1@];
    759         float (*yp)[@nv + 1@] = &y;   // reject: ?+? unpredictable (no functions)
     764        float (*yp)[@nv + 1@] = &y;             // reject: ?+? unpredictable (no functions)
    760765}
    761766\end{cfa}
    762767Yet, both dimension expressions are reused safely.
    763 The @nr@ reference is never written, not volatile meaning no implicit code (load) between declarations, and control does not leave the function between the uses.
     768The @nr@ reference is never written, no implicit code (load) between declarations, and control does not leave the function between the uses.
    764769As well, the build-in @?+?@ function is predictable.
    765770To make these cases work, the programmer must add the follow constant declarations (cast does not work):
     
    768773        @const int nx@ = nr;
    769774        float x[nx];
    770         float (*xp)[nx] = & x;   // accept
     775        float (*xp)[nx] = & x;                  // accept
    771776        @const int ny@ = nv + 1;
    772777        float y[ny];
    773         float (*yp)[ny] = & y;   // accept
     778        float (*yp)[ny] = & y;                  // accept
    774779}
    775780\end{cfa}
     
    808813\end{cfa}
    809814Dimension hoisting already existed in the \CFA compiler.
    810 But its was buggy, particularly with determining, ``Can hoisting the expression be skipped here?'', for skipping this hoisting is clearly desirable in some cases.
     815However, it was buggy, particularly with determining, ``Can hoisting the expression be skipped here?'', for skipping this hoisting is clearly desirable in some cases.
    811816For example, when a programmer has already hoisted to perform an optimization to prelude duplicate code (expression) and/or expression evaluation.
    812817In the new implementation, these cases are correct, harmonized with the accept/reject criteria.
     
    820825\item
    821826Flexible-stride memory:
    822 this model has complete independence between subscripting ordering and memory layout, offering the ability to slice by (provide an index for) any dimension, \eg slice a plane, row, or column, \eg @c[3][*][*]@, @c[3][4][*]@, @c[3][*][5]@.
     827this model has complete independence between subscript ordering and memory layout, offering the ability to slice by (provide an index for) any dimension, \eg slice a row, column, or plane, \eg @c[3][4][*]@, @c[3][*][5]@, @c[3][*][*]@.
    823828\item
    824829Fixed-stride memory:
     
    839844Style 3 is the inevitable target of any array implementation.
    840845The hardware offers this model to the C compiler, with bytes as the unit of displacement.
    841 C offers this model to its programmer as pointer arithmetic, with arbitrary sizes as the unit.
     846C offers this model to programmers as pointer arithmetic, with arbitrary sizes as the unit.
    842847Casting a multidimensional array as a single-dimensional array/pointer, then using @x[i]@ syntax to access its elements, is still a form of pointer arithmetic.
    843848
    844 Now stepping into the implementation of \CFA's new type-1 multidimensional arrays in terms of C's existing type-2 multidimensional arrays, it helps to clarify that even the interface is quite low-level.
    845 A C/\CFA array interface includes the resulting memory layout.
    846 The defining requirement of a type-2 system is the ability to slice a column from a column-finest matrix.
    847 The required memory shape of such a slice is fixed, before any discussion of implementation.
    848 The implementation presented here is how the \CFA array-library wrangles the C type system, to make it do memory steps that are consistent with this layout while not affecting legacy C programs.
     849To step into the implementation of \CFA's new type-1 multidimensional arrays in terms of C's existing type-2 multidimensional arrays, it helps to clarify that the interface is low-level, \ie a C/\CFA array interface includes the resulting memory layout.
     850Specifically, the defining requirement of a type-2 system is the ability to slice a column from a column-finest matrix.
     851Hence, the required memory shape of such a slice is fixed, before any discussion of implementation.
     852The implementation presented here is how the \CFA array-library wrangles the C type system to make it do memory steps that are consistent with this layout while not affecting legacy C programs.
    849853% TODO: do I have/need a presentation of just this layout, just the semantics of -[all]?
    850854
     
    874878\lstinput[aboveskip=0pt]{145-145}{hello-md.cfa}
    875879The nontrivial slicing in this example now allows passing a \emph{noncontiguous} slice to @print1d@, where the new-array library provides a ``subscript by all'' operation for this purpose.
    876 In a multi-dimensional subscript operation, any dimension given as @all@ is a placeholder, \ie ``not yet subscripted by a value'', waiting for such a value, implementing the @ar@ trait.
     880In a multi-dimensional subscript operation, any dimension given as @all@ is a placeholder, \ie ``not yet subscripted by a value'', waiting for a value implementing the @ar@ trait.
    877881\lstinput{150-151}{hello-md.cfa}
    878882
     
    948952A column is almost ready to be arranged into a matrix;
    949953it is the \emph{contained value} of the next-level building block, but another lie about size is required.
    950 At first, an atom needs to be arranged as if it were bigger, but now a column needs to be arranged as if it is smaller (the left diagonal above it, shrinking upward).
     954At first, an atom needs to be arranged as if it is bigger, but now a column needs to be arranged as if it is smaller (the left diagonal above it, shrinking upward).
    951955These lying columns, arranged contiguously according to their size (as announced) form the matrix @x[all]@.
    952956Because @x[all]@ takes indices, first for the fine stride, then for the coarse stride, it achieves the requirement of representing the transpose of @x@.
     
    10201024
    10211025
    1022 \section{Bound Checks, Added and Removed}
    1023 
     1026\section{Zero Overhead}
     1027
     1028At runtime, the \CFA array is exactly a C array.
    10241029\CFA array subscripting is protected with runtime bound checks.
    1025 The array dependent-typing provides information to the C optimizer allowing it remove many of the bound checks.
    1026 This section provides a demonstration of the effect.
    1027 
    1028 The experiment compares the \CFA array system with the padded-room system [TODO:xref] most typically exemplified by Java arrays, but also reflected in the \CC pattern where restricted vector usage models a checked array.
    1029 The essential feature of this padded-room system is the one-to-one correspondence between array instances and the symbolic bounds on which dynamic checks are based.
    1030 The experiment compares with the \CC version to keep access to generated assembly code simple.
     1030The array dependent-typing provides information to the C optimizer, allowing it remove many of the bound checks.
     1031This section provides a demonstration of these effects.
     1032
     1033The experiment compares the \CFA array system with the simple-safety system most typically exemplified by Java arrays (\VRef[Section]{JavaCompare}), but also reflected in the \CC pattern where restricted vector usage models a checked array (\VRef[Section]{CppCompare}).
     1034The essential feature of this simple system is the one-to-one correspondence between array instances and the symbolic bounds on which dynamic checks are based.
     1035The experiment uses the \CC version to simplify access to generated assembly code.
     1036While ``\CC'' labels a participant, it is really the simple-safety system (of @vector@ with @.at@) whose limitations are being explained, and not limitations of \CC optimization.
    10311037
    10321038As a control case, a simple loop (with no reused dimension sizes) is seen to get the same optimization treatment in both the \CFA and \CC versions.
    1033 When the programmer treats the array's bound correctly (making the subscript ``obviously fine''), no dynamic bound check is observed in the program's optimized assembly code.
    1034 But when the bounds are adjusted, such that the subscript is possibly invalid, the bound check appears in the optimized assembly, ready to catch an occurrence the mistake.
    1035 
    1036 TODO: paste source and assembly codes
    1037 
    1038 Incorporating reuse among dimension sizes is seen to give \CFA an advantage at being optimized.
    1039 The case is naive matrix multiplication over a row-major encoding.
    1040 
    1041 TODO: paste source codes
     1039Firstly, when the programmer treats the array's bound correctly (making the subscript ``obviously fine''), no dynamic bound check is observed in the program's optimized assembly code.
     1040But when the bounds are adjusted, such that the subscript is possibly invalid, the bound check appears in the optimized assembly, ready to catch a mistake.
     1041
     1042\VRef[Figure]{f:ovhd-ctl} gives a control-case example of summing values in an array, where each column shows the program in languages C (a,~d,~g), \CFA (b,~e,~h), and \CC (c,~f,~i).
     1043The C code has no bounds checking, while the \CFA and \CC can have bounds checking.
     1044The source-code functions in (a, b, c) can be compiled to have either correct or incorrect uses of bounds.
     1045When compiling for correct bound use, the @BND@ macro passes its argument through, so the loops cover exactly the passed array sizes.
     1046When compiling for possible incorrect bound use (a programming error), the @BND@ macro hardcodes the loops for 100 iterations, which implies out-of-bound access attempts when the passed array has fewer than 100 elements.
     1047The assembly code excerpts show optimized translations for correct-bound mode in (d, e, f) and incorrect-bound mode in (g, h, i).
     1048Because incorrect-bound mode hardcodes 100 iterations, the loop always executes a first time, so this mode does not have the @n == 0@ branch seen in correct-bound mode.
     1049For C, this difference is the only (d--g) difference.
     1050For correct bounds, the \CFA translation equals the C translation, \ie~there is no (d--e) difference, while \CC has an additional indirection to dereference the vector's auxiliary allocation.
     1051
     1052\begin{figure}
     1053\setlength{\tabcolsep}{10pt}
     1054\begin{tabular}{llll@{}}
     1055\multicolumn{1}{c}{C} &
     1056\multicolumn{1}{c}{\CFA} &
     1057\multicolumn{1}{c}{\CC (nested vector)}
     1058\\[1em]
     1059\lstinput{20-28}{ar-bchk/control.c} &
     1060\lstinput{20-28}{ar-bchk/control.cfa} &
     1061\lstinput{20-28}{ar-bchk/control.cc}
     1062\\
     1063\multicolumn{1}{c}{(a)} &
     1064\multicolumn{1}{c}{(b)} &
     1065\multicolumn{1}{c}{(c)}
     1066\\[1em]
     1067\multicolumn{4}{l}{
     1068        \includegraphics[page=1,trim=0 9.125in 2in 0,clip]{ar-bchk}
     1069}
     1070\\
     1071\multicolumn{1}{c}{(d)} &
     1072\multicolumn{1}{c}{(e)} &
     1073\multicolumn{1}{c}{(f)}
     1074\\[1em]
     1075\multicolumn{4}{l}{
     1076        \includegraphics[page=2,trim=0 8.75in 2in 0,clip]{ar-bchk}
     1077}
     1078\\
     1079\multicolumn{1}{c}{(g)} &
     1080\multicolumn{1}{c}{(h)} &
     1081\multicolumn{1}{c}{(i)}
     1082\end{tabular}
     1083\caption{Overhead comparison, control case.
     1084All three programs/compilers generate equally performant code when the programmer ``self-checks'' bounds via a loop's condition.
     1085Yet both \CFA and \CC versions generate code that is slower and safer than C's when the programmer might overrun the bounds.}
     1086\label{f:ovhd-ctl}
     1087\end{figure}
     1088
     1089Differences arise when the bound-incorrect programs are passed an array shorter than 100.
     1090The C version, (g), proceeds with undefined behaviour, reading past the end of the array.
     1091The \CFA and \CC versions, (h, i), flag the mistake with the runtime check, the @i >= n@ branch.
     1092This check is provided implicitly by the library types @array@ and @vector@, respectively.
     1093The significant result is the \emph{absence} of runtime checks from the bound-correct translations, (e, f).
     1094The code optimizer has removed them because, at the point where they would occur (immediately past @.L28@/@.L3@), it knows from the surrounding control flow either @i == 0 && 0 < n@ or @i < n@ (directly), \ie @i < n@ either way.
     1095So any repeated checks, \ie the branch and its consequent code (raise error), are removable.
     1096
     1097% Progressing from the control case, a deliberately bound-incorrect mode is no longer informative.
     1098% Rather, given a (well-typed) program that does good work on good data, the issue is whether it is (determinably) bound-correct on all data.
     1099
     1100When dimension sizes get reused, \CFA has an advantage over \CC-vector at getting simply written programs well optimized.
     1101The example case of \VRef[Figures]{f:ovhd-treat-src} and \VRef[]{f:ovhd-treat-asm} is a simple matrix multiplication over a row-major encoding.
     1102Simple means coding directly to the intuition of the mathematical definition without trying to optimize for memory layout.
     1103In the assembly code of \VRef[Figure]{f:ovhd-treat-asm}, the looping pattern of \VRef[Figure]{f:ovhd-ctl} (d, e, f), ``Skip ahead on zero; loop back for next,'' occurs with three nesting levels.
     1104Simultaneously, the dynamic bound-check pattern of \VRef[Figure]{f:ovhd-ctl} (h,~i), ``Get out on invalid,'' occurs, targeting @.L7@, @.L9@ and @.L8@ (bottom right).
     1105Here, \VRef[Figures]{f:ovhd-treat-asm} shows the \CFA solution optimizing into practically the C solution, while the \CC solution shows added runtime bound checks.
     1106Like in \VRef[Figure]{f:ovhd-ctl} (e), the significance is the \emph{absence} of library-imposed runtime checks, even though the source code is working through the the \CFA @array@ library.
     1107The optimizer removed the library-imposed checks because the data structure @array@-of-@array@ is constrained by its type to be shaped correctly for the intuitive looping.
     1108In \CC, the same constraint does not apply to @vector@-of-@vector@.
     1109Because every individual @vector@ carries its own size, two types of bound mistakes are possible.
     1110
     1111\begin{figure}
     1112\setlength{\tabcolsep}{10pt}
     1113\begin{tabular}{llll@{}}
     1114\multicolumn{1}{c}{C} &
     1115\multicolumn{1}{c}{\CFA} &
     1116\multicolumn{1}{c}{\CC (nested vector)}
     1117\\
     1118\lstinput{20-37}{ar-bchk/treatment.c} &
     1119\lstinput{20-37}{ar-bchk/treatment.cfa} &
     1120\lstinput{20-37}{ar-bchk/treatment.cc}
     1121\end{tabular}
     1122\caption{Overhead comparison, differentiation case, source.}
     1123\label{f:ovhd-treat-src}
     1124\end{figure}
     1125
     1126\begin{figure}
     1127\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}
     1128\begin{tabular}{C{1.5in}C{1.5in}C{1.5in}p{1in}}
     1129C &
     1130\CFA &
     1131\CC (nested vector)
     1132\\[1em]
     1133\multicolumn{4}{l}{
     1134        \includegraphics[page=3,trim=0 4in 2in 0,clip]{ar-bchk}
     1135}
     1136\end{tabular}
     1137\caption{Overhead comparison, differentiation case, assembly.
     1138}
     1139\label{f:ovhd-treat-asm}
     1140\end{figure}
     1141
     1142In detail, the three structures received may not be matrices at all, per the obvious/dense/total interpretation; rather, any one might be ragged-right in its rows.
     1143The \CFA solution guards against this possibility by encoding the minor length (number of columns) in the major element (row) type.
     1144In @res@, for example, each of the @M@ rows is @array(float, N)@, guaranteeing @N@ cells within it.
     1145Or more technically, guaranteeing @N@ as the basis for the imposed bound check \emph{of every row.}
     1146As well, the \CC type does not impose the mathematically familiar constraint of $(M \times P) (P \times N) \rightarrow (M \times N)$.
     1147Even assuming away the first issue, \eg that in @lhs@, all minor/cell counts agree, the data format allows the @rhs@ major/row count to disagree.
     1148Or, the possibility that the row count @res.size()@ disagrees with the row count @lhs.size()@ illustrates this bound-mistake type in isolation.
     1149The \CFA solution guards against this possibility by keeping length information separate from the array data, and therefore eligible for sharing.
     1150This capability lets \CFA escape the one-to-one correspondence between array instances and symbolic bounds, where this correspondence leaves a \CC-vector programmer stuck with a matrix representation that repeats itself.
     1151
     1152It is important to clarify that the \CFA solution does not become unsafe (like C) in losing its dynamic checks, even though it becomes fast (as C) in losing them.
     1153The dynamic checks are dismissed as unnecessary \emph{because} the program is safe to begin with.
     1154To achieve the same performance, a \CC programmer must state appropriate assertions or assumptions, to allow the optimizer to dismiss the runtime checks.
     1155% Especially considering that two of them are in the inner-most loop.
     1156The solution requires doing the work of the inner-loop checks as a \emph{preflight step}.
     1157But this step requires looping and doing it upfront gives too much separation for the optimizer to see ``has been checked already'' in the deep loop.
     1158So, the programmer must restate the preflight observation within the deep loop, but this time as an unchecked assumption.
     1159Such assumptions are risky because they introduce further undefined behaviour when misused.
     1160Only the programmer's discipline remains to ensure this work is done without error.
     1161
     1162In summary, the \CFA solution lets a simply stated program have dynamic guards that catch bugs, while letting a simply stated bug-free program run as fast as the unguarded C equivalent.
     1163
     1164\begin{comment}
     1165The ragged-right issue brings with it a source-of-truth difficulty: Where, in the \CC version, is one to find the value of $N$?  $M$ can come from either @res@'s or @lhs@'s major/row count, and checking these for equality is straightforward.  $P$ can come from @rhs@'s major/row count.  But $N$ is only available from columns, \ie minor/cell counts, which are ragged.  So any choice of initial source of truth, \eg
     1166\end{comment}
    10421167
    10431168
     
    12091334However, it only needs @float@'s default constructor, as the other operations are never used.
    12101335Current work by the \CFA team aims to improve this situation.
    1211 Therefore, I had to construct a workaround.
    1212 
    12131336My workaround moves from otype (value) to dtype (pointer) with a default-constructor assertion, where dtype does not generate any constructors but the assertion claws back the default otype constructor.
    12141337\begin{cquote}
     
    14081531
    14091532\subsection{Java}
     1533\label{JavaCompare}
    14101534
    14111535Java arrays are references, so multi-dimension arrays are arrays-of-arrays \see{\VRef{toc:mdimpl}}.
     
    14961620
    14971621\subsection{\CC}
     1622\label{CppCompare}
    14981623
    14991624Because C arrays are difficult and dangerous, the mantra for \CC programmers is to use @std::vector@ in place of the C array.
    1500 While the vector size can grow and shrink dynamically, \vs a fixed-size dynamic size with VLAs, the cost of this extra feature is mitigated by preallocating the maximum size (like the VLA) at the declaration (one dynamic call) to avoid using @push_back@.
     1625While the vector size can grow and shrink dynamically, \vs an unchanging dynamic size with VLAs, the cost of this extra feature is mitigated by preallocating the maximum size (like the VLA) at the declaration.
     1626So, it costs one upfront dynamic allocation and avoids growing the array through pushing.
    15011627\begin{c++}
    15021628vector< vector< int > > m( 5, vector<int>(8) ); // initialize size of 5 x 8 with 6 dynamic allocations
    15031629\end{c++}
    15041630Multidimensional arrays are arrays-of-arrays with associated costs.
    1505 Each @vector@ array has an array descriptor contain the dimension, which allows bound checked using @x.at(i)@ in place of @x[i]@.
    1506 Used with these restrictions, out-of-bound accesses are caught, and in-bound accesses never exercise the vector's ability to grow, preventing costly reallocate and copy, and never invalidate references to contained values.
    1507 This scheme matches Java's safety and expressiveness exactly, but with the inherent costs.
    1508 
    1509 
     1631Each @vector@ array has an array descriptor containing the dimension, which allows bound checked using @x.at(i)@ in place of @x[i]@.
     1632Used with these restrictions, out-of-bound accesses are caught, and in-bound accesses never exercise the vector's ability to grow, preventing costly reallocate-and-copy, and never invalidating references to contained values.
     1633
     1634This scheme matches a Java array's safety and expressiveness exactly, with the same inherent costs.
     1635Notably, a \CC vector of vectors does not provide contiguous element storage (even when upfront allocation is done carefully) because a vector puts its elements in an auxiliary allocation.
     1636So, in spite of @vector< vector< int > >@ appearing to be ``everything by value,'' it is still a first array whose elements include pointers to further arrays.
     1637
     1638\CC has options for working with memory-adjacent data in desirable ways, particularly in recent revisions.
     1639But none makes an allocation with a dynamically given fixed size less awkward than the vector arrangement just described.
     1640
     1641\CC~26 adds @std::inplace_vector@, which provides an interesting vector--array hybrid,\footnote{
     1642  Like a vector, it lets a user construct elements in a loop, rather than imposing uniform construction.
     1643  Yet it preserves \lstinline{std::array}'s ability to be entirely stack-allocated, by avoiding an auxiliary elements' allocation.
     1644} but does not change the fundamental limit of \lstinline{std::array}, that the length, being a template parameter, must be a static value.
     1645
     1646\CC~20's @std::span@ is a view that unifies true arrays, vectors, static sizes and dynamic sizes, under a common API that adds bounds checking.
     1647When wrapping a vector, bounds checking occurs on regular subscripting, \ie one need not remember to use @.at@.
     1648When wrapping a locally declared fixed-size array, bound communication is implicit.
     1649But it has a soundness gap by offering construction from pointer and user-given length.
     1650
     1651\CC~23's @std::mdspan@ adds multidimensional indexing and reshaping capabilities analogous to those built into \CFA's @array@.
     1652Like @span@, it works over multiple underlying container types.
     1653But neither @span@ nor @mdspan@ augments the available allocation options.
     1654
     1655Thus, these options do not offer an allocation with a dynamically given fixed size.
     1656And furthermore, they do not provide any improvement to the C flexible array member pattern, for making a dynamic amount of storage contiguous with its header, as do \CFA's accordions.
     1657
     1658
     1659\begin{comment}
    15101660\subsection{Levels of Dependently Typed Arrays}
    15111661
     1662TODO: fix the position; checked c does not do linear types
    15121663\CFA's array is the first lightweight application of dependently-typed bound tracking to an extension of C.
    15131664Other extensions of C that apply dependently-typed bound tracking are heavyweight, in that the bound tracking is part of a linearly-typed ownership-system, which further helps guarantee statically the validity of every pointer deference.
     
    15431694it can also do these other cool checks, but watch how I can mess with its conservativeness and termination
    15441695
    1545 Two current, state-of-the-art array languages, Dex\cite{arr:dex:long} and Futhark\cite{arr:futhark:tytheory}, offer novel contributions concerning similar, restricted dependent types for tracking array length.
     1696Two contemporary array-centric languages, Dex\cite{arr:dex:long} and Futhark\cite{arr:futhark:tytheory}, contribute similar, restricted dependent types for tracking array length.
    15461697Unlike \CFA, both are garbage-collected functional languages.
    15471698Because they are garbage-collected, referential integrity is built-in, meaning that the heavyweight analysis, that \CFA aims to avoid, is unnecessary.
     
    15541705There is a particular emphasis on an existential type, enabling callee-determined return shapes.
    15551706
    1556 
    1557 Dex uses a novel conception of size, embedding its quantitative information completely into an ordinary type.
    1558 
    1559 Futhark and full-strength dependently typed languages treat array sizes are ordinary values.
     1707Dex uses an Ada-style conception of size, embedding quantitative information completely into an ordinary type.
     1708
     1709Futhark and full-strength dependently typed languages treat array sizes as ordinary values.
    15601710Futhark restricts these expressions syntactically to variables and constants, while a full-strength dependent system does not.
    15611711
    1562 \CFA's hybrid presentation, @forall( [N] )@, has @N@ belonging to the type system, yet has no instances.
     1712\CFA's hybrid presentation, @forall( [N] )@, has @N@ belonging to the type system, yet no objects of type @[N]@ occur.
    15631713Belonging to the type system means it is inferred at a call site and communicated implicitly, like in Dex and unlike in Futhark.
    15641714Having no instances means there is no type for a variable @i@ that constrains @i@ to be in the range for @N@, unlike Dex, [TODO: verify], but like Futhark.
     
    15691719
    15701720In Ada and Dex, an array is conceived as a function whose domain must satisfy only certain structural assumptions, while in C, \CC, Java, Futhark and \CFA today, the domain is a prefix of the natural numbers.
    1571 The generality has obvious aesthetic benefits for programmers working on scheduling resources to weekdays, and for programmers who prefer to count from an initial number of their own choosing.
     1721The Ada--Dex generality has aesthetic benefits for certain programmers.  For those working on scheduling resources to weekdays:
     1722For those who prefer to count from an initial number of their own choosing:
    15721723
    15731724This change of perspective also lets us remove ubiquitous dynamic bound checks.
     
    16051756(unsafe_from_ordinal a (idiv o bs), unsafe_from_ordinal b (rem o bs))
    16061757\end{cfa}
     1758% fix mike's syntax highlighter
    16071759and by a user-provided adapter expression at the call site that shows how to indexing with a tuple is backed by indexing each dimension at a time
    16081760\begin{cfa}
     
    16161768
    16171769\subsection{Static Safety in C Extensions}
     1770\end{comment}
    16181771
    16191772
    16201773\section{Future Work}
    16211774
    1622 \subsection{Array Syntax}
    1623 
    1624 An important goal is to recast @array(...)@ syntax into C-style @[]@.
    1625 The proposal (which is partially implemented) is an alternate dimension and subscript syntax.
    1626 C multi-dimension and subscripting syntax uses multiple brackets.
    1627 \begin{cfa}
    1628 int m@[2][3]@;  // dimension
    1629 m@[0][1]@ = 3;  // subscript
    1630 \end{cfa}
    1631 Leveraging this syntax, the following (simpler) syntax should be intuitive to C programmers with only a small backwards compatibility issue.
    1632 \begin{cfa}
    1633 int m@[2, 3]@;  // dimension
    1634 m@[0, 1]@ = 3;  // subscript
    1635 \end{cfa}
    1636 However, the new subscript syntax is not backwards compatible, as @0, 1@ is a comma expression.
    1637 Interestingly, disallowed the comma expression in this context eliminates an unreported error: subscripting a matrix with @m[i, j]@ instead of @m[i][j]@, which selects the @j@th row not the @i, j@ element.
    1638 Hence, a comma expression in this context is rare.
    1639 Finally, it is possible to write @m[(i, j)]@ in the new syntax to achieve the equivalent of the old @m[i, j]@.
    1640 Note, the new subscript syntax can easily be internally lowered to @[-][-]...@ and handled as regular subscripting.
    1641 The only ambiguity with C syntax is for a single dimension array, where the syntax for old and new are the same.
    1642 \begin{cfa}
    1643 int m[2@,@];  // single dimension
    1644 m[0] = 3;  // subscript
    1645 \end{cfa}
    1646 The solution for the dimension is to use a terminating comma to denote a new single-dimension array.
    1647 This syntactic form is also used for the (rare) singleton tuple @[y@{\color{red},}@]@.
     1775% \subsection{Array Syntax}
     1776
     1777An important goal is to recast \CFA-style @array(...)@ syntax into C-style array syntax.
     1778The proposal (which is partially implemented) is an alternate dimension and subscript syntax for multi-dimension arrays.
     1779C multi-dimension and subscripting syntax uses multiple bracketed constants/expressions.
     1780\begin{cfa}
     1781int m@[2][3]@;   // dimension
     1782m@[0][1]@ = 3;   // subscript
     1783\end{cfa}
     1784The alternative \CFA syntax is a comma separated list:
     1785\begin{cfa}
     1786int m@[2, 3]@;   // dimension
     1787m@[0, 1]@ = 3;   // subscript
     1788\end{cfa}
     1789which should be intuitive to C programmers and is used in mathematics $M_{i,j}$ and other programing languages, \eg PL/I, Fortran.
     1790With respect to the dimension expressions, C only allows an assignment expression, not a comma expression.
     1791\begin{cfa}
     1792        a[i, j];
     1793test.c:3:16: error: expected ']' before ',' token
     1794\end{cfa}
     1795However, there is an ambiguity for a single dimension array, where the syntax for old and new arrays are the same, @int ar[10]@.
     1796The solution is to use a terminating comma to denote a \CFA-style single-dimension array.
     1797\begin{cfa}
     1798int ar[2$\Huge\color{red},$];  // single dimension new array
     1799\end{cfa}
     1800This syntactic form is also used for the (rare) singleton tuple @[y@{\Large\color{red},}@]@.
    16481801The extra comma in the dimension is only mildly annoying, and acts as eye-candy differentiating old and new arrays.
    1649 The subscript operator is not an issue as overloading selects the correct single-dimension operation for old/new array types.
    1650 The ultimately goal is to replace all C arrays with \CFA arrays, establishing a higher level of safety in C programs, and eliminating the need for the terminating comma.
    1651 
    1652 
     1802Hence, \CFA can repurpose the comma expression in this context for a list of dimensions.
     1803The ultimate goal is to replace all C arrays with \CFA arrays, establishing a higher level of safety in C programs, and eliminating the need for the terminating comma.
     1804With respect to the subscript expression, the comma expression is allowed.
     1805However, a comma expression in this context is rare, and is most commonly a (silent) mistake: subscripting a matrix with @m[i, j]@ instead of @m[i][j]@ selects the @j@th row not the @i, j@ element.
     1806It is still possible to write @m[(i, j)]@ in the new syntax to achieve the equivalent of the old @m[i, j]@.
     1807Internally, the compiler must de-sugar @[i, j, k]@ into @[i][j][k]@ to match with three calls to subscript operators.
     1808Note, there is no ambiguity for subscripting a single dimensional array, as the subscript operator selects the correct form from the array type.
     1809Currently, @array@ supports the old and new subscript syntax \see{\VRef[Figure]{f:ovhd-treat-src}}, including combinations of new and old, @arr[1, 2][3]@.
     1810The new subscript syntax can be extended to C arrays for uniformity, but requires the non-compatible removal of the (rare) comma-expression as a subscript.
     1811
     1812
     1813\begin{comment}
    16531814\subsection{Range Slicing}
    16541815
     
    16591820
    16601821
    1661 \begin{comment}
    16621822\section{\texorpdfstring{\CFA}{Cforall}}
    16631823
     
    16971857Using a compiler-produced value eliminates an opportunity for user error.
    16981858
    1699 TODO: fix in following: even the alloc call gives bad code gen: verify it was always this way; walk back the wording about things just working here; assignment (rebind) seems to offer workaround, as in bkgd-cfa-arrayinteract.cfa
     1859...someday... fix in following: even the alloc call gives bad code gen: verify it was always this way; walk back the wording about things just working here; assignment (rebind) seems to offer workaround, as in bkgd-cfa-arrayinteract.cfa
    17001860
    17011861Bringing in another \CFA feature, reference types, both resolves a sore spot of the last example, and gives a first example of an array-interaction bug.
     
    17061866(*ar2)[5];
    17071867\end{cfa}
    1708 Using ``reference to array'' works at resolving this issue.  TODO: discuss connection with Doug-Lea \CC proposal.
     1868Using ``reference to array'' works at resolving this issue.  ...someday... discuss connection with Doug-Lea \CC proposal.
    17091869\begin{cfa}
    17101870tm (&ar3)[10] = *alloc();
     
    17141874
    17151875Using proper array types (@ar2@ and @ar3@) addresses a concern about using raw element pointers (@ar1@), albeit a theoretical one.
    1716 TODO xref C standard does not claim that @ar1@ may be subscripted,
     1876...someday... xref C standard does not claim that @ar1@ may be subscripted,
    17171877because no stage of interpreting the construction of @ar1@ has it be that ``there is an \emph{array object} here.''
    17181878But both @*ar2@ and the referent of @ar3@ are the results of \emph{typed} @alloc@ calls,
     
    17201880
    17211881The ``reference to array'' type has its sore spots too.
    1722 TODO see also @dimexpr-match-c/REFPARAM_CALL@ (under @TRY_BUG_1@)
    1723 
    1724 TODO: I fixed a bug associated with using an array as a T.  I think.  Did I really?  What was the bug?
     1882...someday... see also @dimexpr-match-c/REFPARAM_CALL@ (under @TRY_BUG_1@)
     1883
     1884...someday... I fixed a bug associated with using an array as a T.  I think.  Did I really?  What was the bug?
    17251885\end{comment}
  • doc/theses/mike_brooks_MMath/background.tex

    r79ba50c r8614140  
    626626    void f( int n, float[][n]  );   $\C{// array of VLAs}$
    627627\end{cfa}
    628 as a repeat, without an error about conflicting types for @f@.
    629 Yet, entirely different stride calculations would occur in a function body whose parameters were declared in each of the two styles.
     628without an error about conflicting types for @f@.
     629Yet, entirely different stride calculations occur in the function body for each of the two parameter styles.
    630630
    631631\begin{figure}
     
    794794
    795795\subsection{Arrays Could be Values}
     796\label{s:ArraysCouldbeValues}
    796797
    797798All arrays have a know runtime size at their point of declaration.
  • doc/theses/mike_brooks_MMath/plots/list-zoomout-noshuf.gp

    r79ba50c r8614140  
    1010set key top left
    1111set logscale x
    12 set logscale y
    13 set yrange [1:1000];
     12#set logscale y
     13#set yrange [1:1000];
    1414set xlabel "List length (item count)" offset 2,0
    1515set ylabel "Duration (ns)"
  • doc/theses/mike_brooks_MMath/plots/list-zoomout-shuf.gp

    r79ba50c r8614140  
    1111set logscale x
    1212set logscale y
    13 set yrange [1:1000];
     13#set yrange [1:1000];
    1414set xlabel "List length (item count)" offset 2,0
    15 set ylabel "Duration (ns)"
     15set ylabel "Duration (ns), log scale"
    1616set linetype 3 dashtype 2
    1717set linetype 4 dashtype 2
  • doc/theses/mike_brooks_MMath/plots/string-peq-cppemu.gp

    r79ba50c r8614140  
    1 set terminal pdf color enhanced size 6.0in,3.0in font "Times,17"
     1set terminal pdf color enhanced size 6.5in,3.5in font "Times,17"
    22#set terminal postscript portrait enhanced size 7.5, 10. color solid 9.5;
    33#set terminal wxt size 950,1250
     
    1111set grid
    1212set key top left
     13set xrange [1:500]
    1314set xtics (1,2,5,10,20,50,100,200,500)
    1415set logscale x
     
    2021set linetype 4 dashtype 2
    2122plot INDIR."/plot-string-peq-cppemu.dat" \
    22            i 0 using 1:2 title columnheader(1)  with points lt rgb "red"  pt  2  ps 1, \
    23         '' i 1 using 1:2 title columnheader(1)  with points lt rgb "red"  pt  1  ps 1, \
    24         '' i 2 using 1:2 title columnheader(1)  with points lt rgb "blue" pt  6  ps 1, \
    25         '' i 3  using 1:2 title columnheader(1) with points lt rgb "blue" pt  8  ps 1
     23           i 0 using 1:2 title columnheader(1)  with points lt rgb "red" pt 2  ps 1, \
     24        '' i 0 using 1:2 notitle smooth sbezier lt rgb "red" dashtype 1, \
     25        '' i 1 using 1:2 title columnheader(1)  with points lt rgb "red" pt 1  ps 1, \
     26        '' i 1 using 1:2 notitle smooth sbezier lt rgb "red" dashtype 4, \
     27        '' i 2 using 1:2 title columnheader(1)  with points lt rgb "blue" pt 6  ps 1, \
     28        '' i 2 using 1:2 notitle smooth sbezier lt rgb "blue" dashtype 1, \
     29        '' i 3 using 1:2 title columnheader(1) with points lt rgb "blue" pt 8  ps 1, \
     30        '' i 3 using 1:2 notitle smooth sbezier lt rgb "blue" dashtype 4 \
  • doc/theses/mike_brooks_MMath/plots/string-peq-sharing.gp

    r79ba50c r8614140  
    1 set terminal pdf color enhanced size 6.0in,3.0in font "Times,17"
     1set terminal pdf color enhanced size 6.5in,3.5in font "Times,17"
    22#set terminal postscript portrait enhanced size 7.5, 10. color solid 9.5;
    33#set terminal wxt size 950,1250
     
    1111set grid
    1212set key top left
     13set xrange [1:500]
    1314set xtics (1,2,5,10,20,50,100,200,500)
    1415set logscale x
     
    2021set linetype 4 dashtype 2
    2122plot INDIR."/plot-string-peq-sharing.dat" \
    22            i 0 using 1:2 title columnheader(1) with points lt rgb "red"  pt  2  ps 1, \
    23         '' i 1 using 1:2 title columnheader(1) with points lt rgb "red"  pt  1  ps 1, \
    24         '' i 2 using 1:2 title columnheader(1) with points lt rgb "blue" pt  6  ps 1, \
    25         '' i 3 using 1:2 title columnheader(1) with points lt rgb "blue" pt  8  ps 1
     23           i 0 using 1:2 title columnheader(1)  with points lt rgb "red" pt 2  ps 1, \
     24        '' i 0 using 1:2 notitle smooth sbezier lt rgb "red" dashtype 1, \
     25        '' i 1 using 1:2 title columnheader(1)  with points lt rgb "red" pt 1  ps 1, \
     26        '' i 1 using 1:2 notitle smooth sbezier lt rgb "red" dashtype 4, \
     27        '' i 2 using 1:2 title columnheader(1)  with points lt rgb "blue" pt 6  ps 1, \
     28        '' i 2 using 1:2 notitle smooth sbezier lt rgb "blue" dashtype 1, \
     29        '' i 3 using 1:2 title columnheader(1) with points lt rgb "blue" pt 8  ps 1, \
     30        '' i 3 using 1:2 notitle smooth sbezier lt rgb "blue" dashtype 4 \
     31
  • doc/theses/mike_brooks_MMath/plots/string-pta-sharing.gp

    r79ba50c r8614140  
    1 set terminal pdf color enhanced size 6.0in,3.0in font "Times,17"
     1set terminal pdf color enhanced size 6.5in,3.5in font "Times,17"
    22#set terminal postscript portrait enhanced size 7.5, 10. color solid 9.5;
    33#set terminal wxt size 950,1250
     
    1111set grid
    1212set key top left
     13set xrange [1:500]
    1314set xtics (1,2,5,10,20,50,100,200,500)
    1415set logscale x
     
    1718set xlabel "String Length being appended (mean, geo. dist.), log scale" offset 2,0
    1819set ylabel "Time per append (ns, mean), log_{2} scale"
    19 #show colornames
    2020plot INDIR."/plot-string-pta-sharing.dat" \
    21            i 0 using 1:2 title columnheader(1) with points lt rgb "red"        pt  2   ps 1, \
    22         '' i 1 using 1:2 title columnheader(1) with points lt rgb "dark-green" pt  4   ps 1, \
    23         '' i 2 using 1:2 title columnheader(1) with points lt rgb "blue"       pt  6   ps 1, \
    24         '' i 3 using 1:2 title columnheader(1) with points lt rgb "dark-green" pt  12  ps 1
     21           i 0 using 1:2 title columnheader(1)  with points lt rgb "red" pt 2  ps 1, \
     22        '' i 0 using 1:2 notitle smooth sbezier lt rgb "red" dashtype 1, \
     23        '' i 1 using 1:2 title columnheader(1)  with points lt rgb "dark-green" pt 4  ps 1, \
     24        '' i 1 using 1:2 notitle smooth sbezier lt rgb "dark-green" dashtype 4, \
     25        '' i 2 using 1:2 title columnheader(1)  with points lt rgb "blue" pt 6  ps 1, \
     26        '' i 2 using 1:2 notitle smooth sbezier lt rgb "blue" dashtype 1, \
     27        '' i 3 using 1:2 title columnheader(1) with points lt rgb "dark-green" pt 12  ps 1, \
     28        '' i 3 using 1:2 notitle smooth sbezier lt rgb "dark-green" dashtype 4 \
     29
  • doc/theses/mike_brooks_MMath/programs/hello-accordion.cfa

    r79ba50c r8614140  
    3131int getPref( @School( C, S ) & school@, int is, int pref ) {
    3232        for ( ic; C ) {
    33                 if ( pref == @school.preferences@[ic][is]; ) return ic; $\C{// offset calculation implicit}$
     33                if ( pref == @school.preferences@[ic][is] ) return ic; $\C{// offset calculation implicit}$
    3434        }
    35         assert( false );
     35        assert( false );        // must find a match
    3636}
    3737
     
    8989
    9090        for ( is; ns ) {
    91                 sout | school.student_ids[is] | ": " | nonl;
     91                sout | school.student_ids[is] | ": ";
    9292                for ( pref; 1 ~= nc ) {
    9393                        int ic = getPref( school, is, pref );
  • doc/theses/mike_brooks_MMath/programs/hello-array.cfa

    r79ba50c r8614140  
    8989
    9090forall( [M], [N] )
    91 void bad( array(float, M) &x,
    92                 array(float, N) &y ) {
     91void f( array(float, M) &x, array(float, N) &y ) {
    9392        f( x, x );              $\C[0.5in]{// ok}$
    9493        f( y, y );              $\C{// ok}$
    95 
    9694        f( x, y );              $\C{// error}\CRT$
     95        if ( M == N ) f( x, @(array( float, M ) &)@y ); $\C{// ok}\CRT$
    9796}
    98 
    9997#endif
    10098
     
    109107
    110108forall( [M], [N] )
    111 void bad_fixed( array( float, M ) & x,
    112                 array( float, N ) & y ) {
     109void f( array( float, M ) & x, array( float, N ) & y ) {
    113110        f( x, x );              $\C[0.5in]{// ok}$
    114111        f( y, y );              $\C{// ok}$
    115         if ( M == N )
    116                 f( x, @(array( float, M ) &)@y ); $\C{// ok}\CRT$
     112        if ( M == N ) f( x, @(array( float, M ) &)@y ); $\C{// ok}\CRT$
    117113}
    118114
     
    132128
    133129forall( [M], [N] )
    134 void bad_ok_only( array(float, M) &x,
    135                 array(float, N) &y ) {
     130void bad_ok_only( array(float, M) &x, array(float, N) &y ) {
    136131        f( x, x );
    137132        f( y, y );
  • doc/theses/mike_brooks_MMath/programs/school1

    r79ba50c r8614140  
    113 courses, 2 students
    2 c\s     90111111 90222222
    3 ENGL101        3        2
    4 PHYS101        1        3
    5 CHEM101        2        1
     2c\s              90111111 90222222
     3ENGL101                 3               2
     4PHYS101                 1               3
     5CHEM101                2               1
  • doc/theses/mike_brooks_MMath/programs/school1.out

    r79ba50c r8614140  
    1 90111111: PHYS101 CHEM101 ENGL101
    2 90222222: CHEM101 ENGL101 PHYS101
     190111111:
     2PHYS101 CHEM101 ENGL101
     390222222:
     4CHEM101 ENGL101 PHYS101
  • doc/theses/mike_brooks_MMath/programs/school2

    r79ba50c r8614140  
    115 courses, 3 students
    2 c\s     90111111 90222222 90333333
    3 ENGL101        3        2        3
    4 PHYS101        1        3        4
    5 CHEM101        2        1        5
    6 PHIL101        4        5        2
    7 MATH499        5        4        1
     2c\s              90111111 90222222 90333333
     3ENGL101                 3               2               3
     4PHYS101                 1               3               4
     5CHEM101                2               1               5
     6PHIL101                   4               5               2
     7MATH499                 5               4               1
  • doc/theses/mike_brooks_MMath/programs/school2.out

    r79ba50c r8614140  
    1 90111111: PHYS101 CHEM101 ENGL101 PHIL101 MATH499
    2 90222222: CHEM101 ENGL101 PHYS101 MATH499 PHIL101
    3 90333333: MATH499 PHIL101 ENGL101 PHYS101 CHEM101
     190111111:
     2PHYS101 CHEM101 ENGL101 PHIL101 MATH499
     390222222:
     4CHEM101 ENGL101 PHYS101 MATH499 PHIL101
     590333333:
     6MATH499 PHIL101 ENGL101 PHYS101 CHEM101
  • doc/theses/mike_brooks_MMath/programs/sharing-demo.cfa

    r79ba50c r8614140  
    300300        open( outfile, "build/sharing10.tex" );
    301301        outfile | "\\begin{cquote}";
     302        outfile | "\\setlength{\\tabcolsep}{10pt}";
    302303        outfile | "\\begin{tabular}{@{}rlllll@{}}";
    303304        outfile | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_crs@\t& @s1_mid@\t& @s1_end@\t\\\\";
  • doc/theses/mike_brooks_MMath/string.tex

    r79ba50c r8614140  
    1717\begin{cquote}
    1818\begin{tabular}{@{}l|l|l|l@{}}
    19 C @char [ ]@                    &  \CC @string@                 & Java @String@ & \CFA @string@ \\
     19C @char [ ]@                    & \CC @string@                  & Java @String@ & \CFA @string@ \\
    2020\hline
    2121@strcpy@, @strncpy@             & @=@                                   & @=@                   & @=@   \\
     
    6060As a result, a @string@ declaration does not specify a maximum length, where a C string array does.
    6161For \CFA, as a @string@ dynamically grows and shrinks in size, so does its underlying storage.
    62 For C, as a string dynamically grows and shrinks in size, but its underlying storage does not.
     62For C, as a string dynamically grows and shrinks in size, its underlying storage does not.
    6363The maximum storage for a \CFA @string@ value is @size_t@ characters, which is $2^{32}$ or $2^{64}$ respectively.
    6464A \CFA string manages its length separately from the string, so there is no null (@'\0'@) terminating value at the end of a string value.
     
    8888Hence, the basic types @char@, @char *@, @int@, @double@, @_Complex@, including any signness and size variations, implicitly convert to type @string@ (as in Java).
    8989\begin{cquote}
    90 \begin{tabular}{@{}l|ll|l@{}}
     90\setlength{\tabcolsep}{10pt}
     91\begin{tabular}{@{}llll@{}}
    9192\begin{cfa}
    9293string s = 5;
     
    128129Conversions can be explicitly specified using a compound literal.
    129130\begin{cfa}
    130 s = (string){ 5 };    s = (string){ "abc" };   s = (string){ 5.5 };
     131s = (string){ 5 };    s = (string){ "abc" };    s = (string){ 5.5 };
    131132\end{cfa}
    132133
    133134Conversions from @string@ to @char *@ attempt to be safe.
    134 The @strncpy@ conversion requires the maximum length for the pointer's target buffer.
     135The overloaded @strncpy@ function is safe, if the length of the C string is correct.
    135136The assignment operator and constructor both allocate the buffer and return its address, meaning the programmer must free it.
    136137Note, a C string is always null terminated, implying storage is always necessary for the null.
    137138\begin{cquote}
    138 \begin{tabular}{@{}l|l@{}}
     139\begin{tabular}{@{}ll@{}}
    139140\begin{cfa}
    140141string s = "abcde";
    141142char cs[4];
    142143strncpy( cs, s, sizeof(cs) );
    143 char * cp = s;          // ownership
     144char * cp = s;            // ownership
    144145delete( cp );
    145146cp = s + ' ' + s;       // ownership
     
    162163\subsection{Length}
    163164
    164 The @len@ operation (short for @strlen@) returns the length of a C or \CFA string.
    165 For compatibility, @strlen@ also works with \CFA strings.
    166 \begin{cquote}
    167 \begin{tabular}{@{}l|l@{}}
     165The @len@ operation (short for @strlen@) returns the length of a C (not including the terminating null) or \CFA string.
     166For compatibility, an overloaded @strlen@ works with \CFA strings.
     167\begin{cquote}
     168\begin{tabular}{@{}ll@{}}
    168169\begin{cfa}
    169170i = len( "" );
     
    192193In C, these operators compare the C string pointer not its value, which does not match programmer expectation.
    193194C strings use function @strcmp@ to lexicographically compare the string value.
    194 Java has the same issue with @==@ and @.equals@.
     195Java has the same issue with @==@ (reference) and @.equals@ (value) comparison.
    195196
    196197
     
    199200The binary operators @+@ and @+=@ concatenate C @char@, @char *@ and \CFA strings, creating the sum of the characters.
    200201\begin{cquote}
    201 \begin{tabular}{@{}l|l@{\hspace{15pt}}l|l@{\hspace{15pt}}l|l@{}}
     202\setlength{\tabcolsep}{5pt}
     203\begin{tabular}{@{}ll|ll|ll@{}}
    202204\begin{cfa}
    203205s = "";
     
    264266Similarly, it is impossible to restrict or remove addition on type @char *@ because (unfortunately) it is subscripting: @cs + 'a'@ implies @cs['a']@ or @'a'[cs]@.
    265267
    266 The prior \CFA concatenation examples show complex mixed-mode interactions among @char@, @char *@, and @string@ constants work correctly (variables are the same).
     268The prior \CFA concatenation examples show complex mixed-mode interactions among @char@, @char *@, and @string@ constants work correctly (@string@ variables are the same).
    267269The reason is that the \CFA type-system handles this kind of overloading well using the left-hand assignment-type and complex conversion costs.
    268270Hence, the type system correctly handles all uses of addition (explicit or implicit) for @char *@.
     
    299301If $N = 0$, a zero length string, @""@, is returned.
    300302\begin{cquote}
    301 \begin{tabular}{@{}l|l@{}}
     303\begin{tabular}{@{}ll@{}}
    302304\begin{cfa}
    303305s = 'x' * 0;
     
    318320multiplication of pointers does not exist in C.
    319321\begin{cfa}
    320 ch = ch * 3;            $\C[2in]{// LHS disambiguate, multiply character values}$
     322ch = ch * 3;            $\C[2in]{// LHS disambiguate, multiply character value}$
    321323s = 'a' * 3;            $\C{// LHS disambiguate, concatenate characters}$
    322324printf( "%c\n", @'a' * 3@ ); $\C{// no LHS information, ambiguous}$
     
    330332The substring operation returns a subset of a string starting at a position in the string and traversing a length, or matching a pattern string.
    331333\begin{cquote}
    332 \setlength{\tabcolsep}{10pt}
    333 \begin{tabular}{@{}l|ll|l@{}}
     334\setlength{\tabcolsep}{8pt}
     335\begin{tabular}{@{}ll|ll@{}}
    334336\multicolumn{2}{@{}c}{\textbf{length}} & \multicolumn{2}{c@{}}{\textbf{pattern}} \\
    335337\multicolumn{4}{@{}l}{\lstinline{string name = "PETER"}} \\
     
    350352"TER"   // clip length to 3
    351353"ER"
    352 ""                 // beyond string to right, clip to null
    353 ""                 // beyond string to left, clip to null
     354""                 // clip, beyond right
     355""                 // clip, beyond left
    354356"ER"
    355357"TER"   // to end of string
     
    390392Hence, the left string may decrease, stay the same, or increase in length.
    391393\begin{cquote}
    392 \begin{tabular}{@{}l|l@{}}
     394\begin{tabular}{@{}ll@{}}
    393395\begin{cfa}[escapechar={}]
    394396digit( 3, 3 ) = "";
     
    408410\end{tabular}
    409411\end{cquote}
    410 Now substring pattern matching is useful on the left-hand side of assignment.
    411 \begin{cquote}
    412 \begin{tabular}{@{}l|l@{}}
     412Here, substring pattern matching is useful on the left-hand side of assignment.
     413\begin{cquote}
     414\begin{tabular}{@{}ll@{}}
    413415\begin{cfa}[escapechar={}]
    414416digit( "$$" ) = "345";
     
    422424\end{tabular}
    423425\end{cquote}
    424 Extending the pattern to a regular expression is a possible extension.
     426Supporting a regular-expression pattern is a possible extension.
    425427
    426428The replace operation extends substring to substitute all occurrences.
    427429\begin{cquote}
    428 \begin{tabular}{@{}l|l@{}}
     430\begin{tabular}{@{}ll@{}}
    429431\begin{cfa}
    430432s = replace( "PETER", "E", "XX" );
     
    448450If the key does not appear in the string, the length of the string is returned.
    449451\begin{cquote}
    450 \begin{tabular}{@{}l|l@{}}
     452\begin{tabular}{@{}ll@{}}
    451453\begin{cfa}
    452454i = find( digit, '3' );
     
    465467A character-class operation indicates if a string is composed completely of a particular class of characters, \eg, alphabetic, numeric, vowels, \etc.
    466468\begin{cquote}
    467 \begin{tabular}{@{}l|l@{}}
     469\begin{tabular}{@{}ll@{}}
    468470\begin{cfa}
    469471charclass vowels{ "aeiouy" };
     
    484486Function @exclude@ is the reverse of @include@, checking if all characters in the string are excluded from the class (compliance).
    485487\begin{cquote}
    486 \begin{tabular}{@{}l|l@{}}
     488\begin{tabular}{@{}ll@{}}
    487489\begin{cfa}
    488490i = exclude( "cdbfghmk", vowels );
     
    498500Both forms can return the longest substring of compliant characters.
    499501\begin{cquote}
    500 \begin{tabular}{@{}l|l@{}}
     502\begin{tabular}{@{}ll@{}}
    501503\begin{cfa}
    502504s = include( "aaeiuyoo", vowels );
     
    517519There are also versions of @include@ and @exclude@, returning a position or string, taking a validation function, like one of the C character-class functions.\footnote{It is part of the hereditary of C that these function take and return an \lstinline{int} rather than a \lstinline{bool}, which affects the function type.}
    518520\begin{cquote}
    519 \begin{tabular}{@{}l|l@{}}
     521\begin{tabular}{@{}ll@{}}
    520522\begin{cfa}
    521523i = include( "1FeC34aB", @isxdigit@ );
     
    536538The translate operation returns a string with each character transformed by one of the C character transformation functions.
    537539\begin{cquote}
    538 \begin{tabular}{@{}l|l@{}}
     540\begin{tabular}{@{}ll@{}}
    539541\begin{cfa}
    540542s = translate( "abc", @toupper@ );
     
    559561However, string search can fail, which is reported as an alternate search outcome, possibly an exception.
    560562Many string libraries use a return code to indicate search failure, with a failure value of @0@ or @-1@ (PL/I~\cite{PLI} returns @0@).
    561 This semantics leads to the awkward pattern, which can appear many times in a string library or user code.
     563This semantics leads to an awkward pattern, which can appear many times in a string library or user code.
    562564\begin{cfa}
    563565i = exclude( s, alpha );
     
    565567else return "";
    566568\end{cfa}
     569The problem is that substring does the wrong thing or fails with the failure return-code in most string libraries, so it has to be special cased.
    567570
    568571\CFA adopts a return code but the failure value is taken from the index-of function in APL~\cite{apl}, which returns the length of the target string $N$ (or $N+1$ for 1 origin).
     
    582585\begin{figure}
    583586\begin{cquote}
    584 \begin{tabular}{@{}l|l@{}}
     587\begin{tabular}{@{}ll@{}}
    585588\multicolumn{1}{c}{\textbf{\CC}} & \multicolumn{1}{c}{\textbf{\CFA}} \\
    586589\begin{cfa}
     
    628631\begin{cquote}
    629632\begin{tabular}{@{}ll@{}}
    630 \begin{cfa}
    631 char s[32];   // string s;
     633\multicolumn{2}{@{}l@{}}{\lstinline{char s[32];   // changing s's type to string works}} \\
     634\begin{cfa}
    632635strlen( s );
    633636strnlen( s, 3 );
     
    637640&
    638641\begin{cfa}
    639 
    640642strcpy( s, "abc" );
    641643strncpy( s, "abcdef", 3 );
     
    651653\subsection{I/O Operators}
    652654
    653 The ability to input and output strings is as essential as for any other type.
    654 The goal for character I/O is to also work with groups rather than individual characters.
     655The ability to input and output a string is as essential as for any other type.
     656The goal for character I/O is to work with groups rather than individual characters.
    655657A comparison with \CC string I/O is presented as a counterpoint to \CFA string I/O.
    656658
     
    659661The \CC manipulators are @setw@, and its associated width controls @left@, @right@ and @setfill@.
    660662\begin{cquote}
    661 \begin{tabular}{@{}l|l@{}}
     663\begin{tabular}{@{}ll@{}}
    662664\begin{c++}
    663665string s = "abc";
     
    676678The \CFA manipulators are @bin@, @oct@, @hex@, @wd@, and its associated width control and @left@.
    677679\begin{cquote}
    678 \begin{tabular}{@{}l|l@{}}
     680\begin{tabular}{@{}ll@{}}
    679681\begin{cfa}
    680682string s = "abc";
     
    704706Reading into a @char@ is safe as the size is 1, @char *@ is unsafe without using @setw@ to constraint the length (which includes @'\0'@), @string@ is safe as its grows dynamically as characters are read.
    705707\begin{cquote}
    706 \begin{tabular}{@{}l|l@{}}
     708\begin{tabular}{@{}ll@{}}
    707709\begin{c++}
    708710char ch, c[10];
     
    721723\end{cquote}
    722724Input text can be \emph{gulped}, including whitespace, from the current point to an arbitrary delimiter character using @getline@.
     725\begin{cquote}
     726\setlength{\tabcolsep}{10pt}
     727\begin{tabular}{@{}ll@{}}
     728\multicolumn{1}{c}{\textbf{\CC}} & \multicolumn{1}{c}{\textbf{\CFA}} \\
     729\begin{cfa}
     730string s1, s2, s3;
     731getline( cin, s1, 'a' );
     732getline( cin, s2, 'w' );
     733getline( cin, s3 );
     734cout << s1 << ' ' << s2 << ' ' << s3 << endl;
     735@bbbad ddwxyz@
     736\end{cfa}
     737&
     738\begin{cfa}
     739
     740sin | getline( s1, 'a' )
     741        | getline( s2, 'w' )
     742        | getline( s3 );
     743sout | s1 | s2 | s3;       "bbb" "d dd" "xyz"
     744
     745\end{cfa}
     746\end{tabular}
     747
     748\end{cquote}
    723749
    724750The \CFA philosophy for input is that, for every constant type in C, these constants should be usable as input.
     
    730756\begin{cquote}
    731757\setlength{\tabcolsep}{10pt}
    732 \begin{tabular}{@{}l|l@{}}
     758\begin{tabular}{@{}ll@{}}
    733759\begin{c++}
    734760char ch, c[10];
     
    736762sin | ch | wdi( 5, c ) | s;
    737763@abcde fg@
    738 sin | quote( ch ) | quote( wdi( sizeof(c), c ) ) | quote( s, '[', ']' ) | nl;
    739 @'a' "bcde" [fg]@
     764sin | @quote@( ch ) | @quote@( wdi( sizeof(c), c ) ) | @quote@( s, '[', ']' ) | nl;
     765@'a'   "bcde"      [fg]@
    740766sin | incl( "a-zA-Z0-9 ?!&\n", s ) | nl;
    741767@x?&000xyz TOM !.@
     
    767793For example, the \CC @replace@ function selects a substring in the target and substitutes it with the source string, which can be smaller or larger than the substring.
    768794\CC modifies the mutable receiver object, replacing by position (zero origin) and length.
    769 \begin{cquote}
    770 \begin{tabular}{@{}l|l@{}}
    771795\begin{c++}
    772796string s1 = "abcde";
    773 s1.replace( 2, 3, "xy" );
     797s1.replace( 2, 3, "xy" );                        "abxy"
    774798\end{c++}
    775 &
    776 \begin{c++}
    777 
    778 "abxy"
    779 \end{c++}
    780 \end{tabular}
    781 \end{cquote}
    782799Java cannot modify the receiver (immutable strings) so it returns a new string, replacing by text.
    783800\label{p:JavaReplace}
    784 \begin{cquote}
    785 \begin{tabular}{@{}l|l@{}}
    786801\begin{java}
    787802String s = "abcde";
    788 String r = s.replace( "cde", "xy" );
     803String r = s.replace( "cde", "xy" );      "abxy"
    789804\end{java}
    790 &
    791 \begin{java}
    792 
    793 "abxy"
    794 \end{java}
    795 \end{tabular}
    796 \end{cquote}
    797805Java also provides a mutable @StringBuffer@, replacing by position (zero origin) and length.
    798 \begin{cquote}
    799 \begin{tabular}{@{}l|l@{}}
    800806\begin{java}
    801807StringBuffer sb = new StringBuffer( "abcde" );
    802 sb.replace( 2, 5, "xy" );
     808sb.replace( 2, 5, "xy" );                         "abxy"
    803809\end{java}
    804 &
    805 \begin{java}
    806 
    807 "abxy"
    808 \end{java}
    809 \end{tabular}
    810 \end{cquote}
    811810However, there are anomalies.
    812811@StringBuffer@'s @substring@ returns a @String@ copy that is immutable rather than modifying the receiver.
     
    818817\begin{figure}
    819818\setlength{\extrarowheight}{2pt}
    820 \begin{tabularx}{\textwidth}{@{}p{0.6in}XXcccc@{}}
     819\setlength{\tabcolsep}{5pt}
     820\begin{tabularx}{\textwidth}{@{}p{0.8in}XXcccc@{}}
    821821                                        &                       &                       & \multicolumn{4}{@{}c@{}}{\underline{Supports Helpful?}} \\
    822822                                        & Required      & Helpful       & C                     & \CC           & Java          & \CFA \\
    823823\hline
    824 Type abst'n
     824Type Abstraction
    825825                                        & Low-level: The string type is a varying amount of text communicated via a parameter or return.
    826826                                                                & High-level: The string-typed relieves the user of managing memory for the text.
     
    913913String s3 = s2.substring( 1, 2 );  $\C{// snapshot state (possible), strict symmetry, fragment referent}\CRT$
    914914System.out.println( s + ' ' + s1 + ' ' + s2 + ' ' + s3 );
     915$\texttt{\small abcde abcde bc c}$
    915916System.out.println( (s == s1) + " " + (s == s2) + " " + (s2 == s3) );
    916 $\texttt{\small abcde abcde bc c}$
    917917$\texttt{\small true false false}$
    918918\end{java}
     
    939939string s3 = s`share; $\C{// alias state, strict symmetry, variable-constrained referent}$
    940940string s4 = s( 1, 2 ); $\C{// snapshot state, strict symmetry, fragment referent}$
    941 string s5 = s4( 1, 1 )`share'; $\C{// alias state, strict symmetry, fragment referent}\CRT$
     941string s5 = s4( 1, 1 )`share; $\C{// alias state, strict symmetry, fragment referent}\CRT$
    942942sout | s | s1 | s2 | s3 | s4 | s5;
    943943$\texttt{\small abcde abcde abcde abcde bc c}$
     
    995995
    996996String sharing is expressed using the @`share@ marker to indicate aliasing (mutations shared) \vs snapshot (not quite an immutable result, but one with subsequent mutations isolated).
    997 This aliasing relationship is a sticky property established at initialization.
     997This aliasing relationship is a \newterm{sticky property} established at initialization.
    998998For example, here strings @s1@ and @s1a@ are in an aliasing relationship, while @s2@ is in a copy relationship.
    999999\input{sharing1.tex}
     
    10301030When changes happen on an aliasing substring that overlap.
    10311031\input{sharing10.tex}
    1032 Strings @s1_crs@ and @s1_mid@ overlap at character 4, @j@, because the substrings are 3,2 and 4,2.
     1032Strings @s1_crs@ and @s1_mid@ overlap at character 4, @'j'@, because the substrings are 3,2 and 4,2.
    10331033When @s1_crs@'s size increases by 1, @s1_mid@'s starting location moves from 4 to 5, but the overlapping character remains, changing to @'+'@.
    10341034
     
    11361136Normally, one global context is appropriate for an entire program;
    11371137concurrency is discussed in \VRef{s:ControllingImplicitSharing}.
    1138 A string is a handle to a node in a linked list containing a information about a string text in the buffer.
     1138A string is a handle to a node in a linked list containing information about a string text in the buffer.
    11391139The list is doubly linked for $O(1)$ insertion and removal at any location.
    11401140Strings are ordered in the list by text start address.
     
    11511151The linked handles define all live strings in the buffer, which indirectly defines the allocated and free space in the buffer.
    11521152The string handles are maintained in sorted order, so the handle list can be traversed, copying the first live text to the start of the buffer, and subsequent strings after each other.
    1153 After compaction, if free storage is still be less than the new string allocation, a larger text buffer is heap-allocated, the current buffer is copied into the new buffer, and the original buffer is freed.
     1153After compaction, if free storage is still less than the new string allocation, a larger text buffer is heap-allocated, the current buffer is copied into the new buffer, and the original buffer is freed.
    11541154Note, the list of string handles is structurally unaffected during a compaction;
    11551155only the text pointers in the handles are modified to new buffer locations.
     
    11581158There are two fundamental string-creation functions: importing external text like a C-string or reading a string, and initialization from an existing \CFA string.
    11591159When importing, storage comes from the end of the buffer, into which the text is copied.
    1160 The new string handle is inserted at the end of the handle list because the new text is at the end of the buffer.
     1160To maintain sorted order, the new string handle is inserted at the end of the handle list because the new text is at the end of the buffer.
    11611161When initializing from text already in the buffer, the new handle is a second reference into the original run of characters.
    1162 In this case, the new handle's linked-list position is after the original handle.
     1162To maintain sorted order, the new handle's linked-list position is after the original handle.
    11631163Both string initialization styles preserve the string module's internal invariant that the linked-list order matches the buffer order.
    11641164For string destruction, handles are removed from the list.
     
    11771177Favourable conditions allow for in-place editing: where there is room for the resulting value in the original buffer location, and where all handles referring to the original buffer location see the new value.
    11781178One notable example of favourable conditions occurs because the most recently written string is often the last in the buffer, after which a large amount of free space occurs.
    1179 So, repeated appends often occur without copying previously accumulated characters.
     1179Now, repeated appends (reading) can occur without copying previously accumulated characters.
    11801180However, the general case requires a new buffer allocation: where the new value does not fit in the old place, or if other handles are still using the old value.
    11811181
     
    11941194Both \CC and \CFA RAII systems are powerful enough to achieve reference counting.
    11951195
    1196 In general, a lifecycle function has access to an object by location, \ie constructors and destructors receive a @this@ parameter providing an object's memory address.
     1196In general, a lifecycle function has access to an object by location, \ie constructors and destructors receive a parameter providing an object's memory address.\footnote{
     1197Historically in \CC, the type of \lstinline[language=C++]{this} is a pointer versus a reference;
     1198in \CFA, the first parameter of a constructor or destructor must be a reference.}
    11971199\begin{cfa}
    11981200struct S { int * ip; };
    11991201void ?{}( S & @this@ ) { this.ip = new(); } $\C[3in]{// default constructor}$
    1200 void ?{}( S & @this@, int i ) { (this){}; *this.ip = i; } $\C{// initializing constructor}$
    1201 void ?{}( S & @this@, S s ) { (this){*s.ip}; } $\C{// copy constructor}$
     1202void ?{}( S & @this@, int i ) { this{}; *this.ip = i; } $\C{// initializing constructor}$
     1203void ?{}( S & @this@, S s ) { this{ *s.ip }; } $\C{// copy constructor}$
    12021204void ^?{}( S & @this@ ) { delete( this.ip ); } $\C{// destructor}\CRT$
    12031205\end{cfa}
    12041206Such basic examples use the @this@ address only to gain access to the values being managed.
    1205 But the lifecycle logic can use the pointer generally, too.
    1206 For example, they can add @this@ object to a collection at creation and remove it at destruction.
    1207 \begin{cfa}
    1208 // header
    1209 struct T {
     1207But lifecycle logic can use the address, too, \eg add the @this@ object to a collection at creation and remove it at destruction.
     1208\begin{cfa}
     1209// header (.hfa)
     1210struct N { $\C[3in]{// list node}$
    12101211        // private
    1211         inline dlink(T);
     1212        inline dlink( N );
    12121213};
    1213 void ?{}( T & ); $\C[3in]{// default constructor}$
    1214 void ^?{}( T & ); $\C{// destructor}\CRT$
    1215 // implementation
    1216 static dlist(T) @all_T@;
    1217 void ?{}( T & this ) { insert_last(all_T, @this@) }
    1218 void ^?{}( T & this ) { remove(this); }
    1219 \end{cfa}
    1220 A module providing the @T@ type can traverse @all_T@ at relevant times, to keep the objects ``good.''
    1221 Hence, declaring a @T@ not only ensures that it begins with an initially ``good'' value, but it also provides an implicit subscription to a service that keeps the value ``good'' during its lifetime.
     1214void ?{}( N & ); $\C{// default constructor}$
     1215void ^?{}( N & ); $\C{// destructor}\CRT$
     1216// implementation (.cfa)
     1217static dlist( N ) @list_N@;
     1218void ?{}( N & this ) { insert_last( list_N, @this@ ) }
     1219void ^?{}( N & this ) { remove( this ); }
     1220\end{cfa}
     1221A module providing the @N@ (node) type can traverse @list_N@ to manipulate the objects.
     1222Hence, declaring a @N@ not only ensures that it begins with an initially ``good'' value, but it also provides an implicit subscription to a service that keeps the value ``good'' during its lifetime.
    12221223Again, both \CFA and \CC support this usage style.
    12231224
     
    12261227In the parameter direction, the language's function-call handling must arrange for a copy-constructor call to happen, at a time near the control transfer into the callee. %, with the source as the caller's (sender's) version and the target as the callee's (receiver's) version.
    12271228In the return direction, the roles are reversed and the copy-constructor call happens near the return of control.
    1228 \CC supports this capability.% without qualification.
     1229\CC supports this capability. % without qualification.
    12291230\CFA offers limited support;
    1230 simple examples work, but implicit copying does not combine successfully with the other RAII capabilities discussed.
     1231simple examples work, but implicit copying does not combine successfully with other RAII capabilities.
    12311232
    12321233\CC also offers move constructors and return-value optimization~\cite{RVO20}.
     
    12391240\begin{enumerate}
    12401241\item
     1242\label{p:feature1}
    12411243        Object provider implements lifecycle functions to manage a resource outside of the object.
    12421244\item
    1243         Object provider implements lifecycle functions to store references back to the object, often originating from outside of it.
     1245\label{p:feature2}
     1246        Object provider implements lifecycle functions to store references to the object, often originating from outside of it.
    12441247\item
     1248\label{p:feature3}
    12451249        Object user expects to pass (in either direction) an object by value for function calls.
    12461250\end{enumerate}
    1247 \CC supports all three simultaneously.  \CFA does not currently support \#2 and \#3 on the same object, though \#1 works along with either one of \#2 or \#3.  \CFA needs to be fixed to support all three simultaneously.
    1248 
    1249 The reason that \CFA does not support \#2 with \#3 is a holdover from how \CFA function calls lowered to C, before \CFA got references and RAII.
    1250 At that time, adhering to a principal of minimal intervention, this code could always be treated as passthrough:
     1251\CC supports all three simultaneously.
     1252\CFA does not currently support \ref{p:feature2} and \ref{p:feature3} on the same object, though \ref{p:feature1} works along with either one of \ref{p:feature2} or \ref{p:feature3}.
     1253\CFA needs to be fixed to support all three simultaneously.
     1254
     1255The reason \CFA does not support \ref{p:feature2} with \ref{p:feature3} is a holdover from how \CFA lowered function calls to C, before \CFA got references and RAII.
     1256At that time, adhering to a principal of minimal intervention, this code was treated as a passthrough:
    12511257\begin{cfa}
    12521258struct U { ... };
    12531259// RAII to go here
    1254 void f( U u ) { F_BODY(u) }
     1260void f( U u ) { F_BODY( u ) }
    12551261U x;
    12561262f( x );
    12571263\end{cfa}
    1258 But adding custom RAII (at ``...go here'') changes things.
    1259 The common \CC lowering~\cite[Sec. 3.1.2.3]{cxx:raii-abi} proceeds differently than the present \CFA lowering.
    1260 \begin{cquote}
     1264However, adding custom RAII (at ``...go here'') changes things.
     1265
     1266\VRef[Figure]{f:CodeLoweringRAII} shows the common \CC lowering~\cite[Sec. 3.1.2.3]{cxx:raii-abi} (right) proceeds differently than the present \CFA lowering (left).
     1267The current \CFA scheme is still using a by-value C call.
     1268C does a @memcpy@ on structures passed by value.
     1269And so, @F_BODY@ sees the bits of @__u_for_f@ occurring at an address that has never been presented to the @U@ lifecycle functions.
     1270If @U@ is trying to have a style- \ref{p:feature2} invariant, it shows up broken in @F_BODY@: references supposedly to @u@ are actually to @__u_for_f@.
     1271The \CC scheme does not have this problem because it constructs the @u@ copy in the correct location within @f@.
     1272Yet, the current \CFA scheme is sufficient to deliver style-\ref{p:feature1} invariants (in this style-\ref{p:feature3} use case) because this scheme still does the correct number of lifecycle calls, using correct values, at correct times.
     1273So, reference-counting or simple ownership applications get their invariants respected under call/return-by-value.
     1274
     1275\begin{figure}
     1276\centering
    12611277\begin{tabular}{@{}l|l@{}}
    1262 \begin{cfa}
    1263 $\C[0.0in]{// \CC, \CFA future}\CRT$
     1278\multicolumn{1}{@{}c|}{\CFA today} & \multicolumn{1}{c@{}}{\CC, \CFA future} \\
     1279\begin{cfa}
     1280struct U {...};
     1281// RAII elided
     1282void f( U u ) {
     1283
     1284        F_BODY( u );
     1285
     1286}
     1287U x; // call default ctor
     1288{
     1289        @U __u_for_f = x;@  // call copy ctor
     1290        f( __u_for_f );
     1291        // call dtor, __u_for_f
     1292}
     1293// call dtor, x
     1294\end{cfa}
     1295&
     1296\begin{cfa}
    12641297struct U {...};
    12651298// RAII elided
    12661299void f( U * __u_orig ) {
    1267         U u = * __u_orig;  // call copy ctor
     1300        @U u = * __u_orig;@  // call copy ctor
    12681301        F_BODY( u );
    12691302        // call dtor, u
     
    12771310// call dtor, x
    12781311\end{cfa}
    1279 &
    1280 \begin{cfa}
    1281 $\C[0.0in]{// \CFA today}\CRT$
    1282 struct U {...};
    1283 // RAII elided
    1284 void f( U u ) {
    1285 
    1286         F_BODY( u );
    1287 
    1288 }
    1289 U x; // call default ctor
    1290 {
    1291         U __u_for_f = x;  // call copy ctor
    1292         f( __u_for_f );
    1293         // call dtor, __u_for_f
    1294 }
    1295 // call dtor, x
    1296 \end{cfa}
    1297 \end{tabular}
    1298 \end{cquote}
    1299 The current \CFA scheme is still using a by-value C call.
    1300 C does a @memcpy@ on structures passed by value.
    1301 And so, @F_BODY@ sees the bits of @__u_for_f@ occurring at an address that has never been presented to the @U@ lifecycle functions.
    1302 If @U@ is trying to have a style-\#2 invariant, it shows up broken in @F_BODY@: references supposedly to @u@ are actually to @__u_for_f@.
    1303 The \CC scheme does not have this problem because it constructs the for @f@ copy in the correct location within @f@.
    1304 
    1305 Yet, the current \CFA scheme is sufficient to deliver style-\#1 invariants (in this style-\#3 use case) because this scheme still does the correct number of lifecycle calls, using correct values, at correct times.
    1306 So, reference-counting or simple ownership applications get their invariants respected under call/return-by-value.
     1312\end{tabular}
     1313
     1314\caption{Code Lowering for RAII}
     1315\label{f:CodeLoweringRAII}
     1316\end{figure}
    13071317
    13081318% [Mike is not currently seeing how distinguishing initialization from assignment is relevant]
     
    13381348% The following discusses the consequences of this semantics with respect to lifetime management of \CFA strings.
    13391349
    1340 The string API offers style \#3's pass-by-value in, \eg in the return of @"a" + "b"@.
    1341 Its implementation uses the style-\#2 invariant of the string handles being linked to each other, helping to achieve high performance.
     1350The string API offers style \ref{p:feature3}'s pass-by-value, \eg in the return of @"a" + "b"@.
     1351Its implementation uses the style-\ref{p:feature2} invariant of the string handles being linked to each other, helping to achieve high performance.
    13421352Since these two RAII styles cannot coexist, a workaround splits the API into two layers: one that provides pass-by-value, built upon the other with inter-linked handles.
    13431353The layer with pass-by-value incurs a performance penalty, while the layer without delivers the desired runtime performance.
     
    13451355Both APIs present the same features, up to return-by-value operations being unavailable in LL and implemented via the workaround in HL.
    13461356The intention is for most future code to target HL.
    1347 When the RAII issue is fixed, the full HL feature set will be achievable using the LL-style lifetime management.
    1348 Then, HL will be removed;
    1349 LL's type will be renamed @string@ and programs written for current HL will run faster.
     1357When the RAII issue is fixed, the full HL feature set is achievable using the LL-style lifetime management.
     1358Then, HL can be removed, LL's type renamed to @string@, and programs generated with the current HL will run faster.
    13501359In the meantime, performance-critical sections of applications must use LL.
    13511360Subsequent performance experiments \see{\VRef{s:PerformanceAssessment}} use the LL API when comparing \CFA to other languages.
    13521361This measurement gives a fair estimate of the goal state for \CFA.
    13531362A separate measure of the HL overhead is also included.
    1354 hence, \VRef[Section]{string-general-impl} us describing the goal state for \CFA.
    1355 In present state, the type @string_res@ replaces its mention of @string@ as inter-linked handle.
     1363Hence, \VRef[Section]{string-general-impl} is describing the goal state for \CFA.
     1364In present state, the internal type @string_res@ replaces @string@ for an inter-linked handle.
    13561365
    13571366To use LL, a programmer rewrites invocations using pass-by-value APIs into invocations where resourcing is more explicit.
    13581367Many invocations are unaffected, notably assignment and comparison.
    1359 Of the capabilities listed in \VRef[Figure]{f:StrApiCompare}, only the following three cases need revisions.
    1360 \begin{cquote}
    1361 \begin{tabular}{ll}
     1368\VRef[Figure]{f:HL_LL_Lowering} shows, of the capabilities listed in \VRef[Figure]{f:StrApiCompare}, only three cases need revisions.
     1369The actual HL workaround wraps @string@ as a pointer to a uniquely owned, heap-allocated @string_res@.
     1370This arrangement has @string@ using style-\ref{p:feature1} RAII, which is compatible with pass-by-value.
     1371
     1372\begin{figure}
     1373\centering
     1374\begin{tabular}{@{}ll@{}}
    13621375HL & LL \\
    13631376\hline
     
    13751388\begin{cfa}
    13761389string s = "abcde";
    1377 string s2 = s(2, 3); // s2 == "cde"
    1378 
    1379 s(2,3) = "x"; // s == "abx" && s2 == "cde"
     1390string s2 = s(2, 3);   // s2 == "cde"
     1391
     1392s(2,3) = "x";   // s == "abx" && s2 == "cde"
    13801393\end{cfa}
    13811394&
    13821395\begin{cfa}
    13831396string_res sr = "abcde";
    1384 string_res sr2 = {sr, 2, 3}; // sr2 == "cde"
     1397string_res sr2 = {sr, 2, 3};   // sr2 == "cde"
    13851398string_res sr_mid = { sr, 2, 3, SHARE };
    1386 sr_mid = "x"; // sr == "abx" && sr2 == "cde"
     1399sr_mid = "x";   // sr == "abx" && sr2 == "cde"
    13871400\end{cfa}
    13881401\\
     
    13911404string s = "abcde";
    13921405
    1393 s[2] = "xxx";  // s == "abxxxde"
     1406s[2] = "xxx";    // s == "abxxxde"
    13941407\end{cfa}
    13951408&
     
    13971410string_res sr = "abcde";
    13981411string_res sr_mid = { sr, 2, 1, SHARE };
    1399 mid = "xxx"; // sr == "abxxxde"
    1400 \end{cfa}
    1401 \end{tabular}
    1402 \end{cquote}
    1403 The actual HL workaround is having @string@ wrap a pointer to a uniquely owned, heap-allocated @string_res@.  This arrangement has @string@ being style-\#1 RAII, which is compatible with pass-by-value.
     1412mid = "xxx";   // sr == "abxxxde"
     1413\end{cfa}
     1414\end{tabular}
     1415
     1416\caption{HL to LL Lowering}
     1417\label{f:HL_LL_Lowering}
     1418\end{figure}
    14041419
    14051420
     
    15051520It might be possible to pack 16- or 32-bit Unicode characters within the same string buffer as 8-bit characters.
    15061521Again, locations for identification flags must be found and checked along the fast path to select the correct actions.
    1507 Handling utf8 (variable length), is more problematic because simple pointer arithmetic cannot be used to stride through the variable-length characters.
     1522Handling utf8 (variable length) is more problematic because simple pointer arithmetic cannot be used to stride through the variable-length characters.
    15081523Trying to use a secondary array of fixed-sized pointers/offsets to the characters is possible, but raises the question of storage management for the utf8 characters themselves.
    15091524
     
    15131528
    15141529I assessed the \CFA string library's speed and memory usage against strings in \CC STL.
    1515 Overall, this analysis shows that adding support for the features shown earlier in the chapter comes at no substantial cost in the performance of features common to both APIs.
    1516 
    1517 Moreover, the results support the \CFA string's position as a high-level enabler of simplified text processing.
    1518 STL makes its user think about memory management.
     1530Overall, this analysis shows that features common to both APIs comes at no substantial cost in the performance.
     1531Moreover, the comparison shows that \CFA's high-level string features simplify text processing because the STL requires users to think more about memory management.
    15191532When the user does, and is successful, STL's performance can be very good.
    1520 But when the user fails to think through the consequences of the STL representation, performance becomes poor.
     1533But if a user does understand the consequences of the STL representation, performance becomes poor.
    15211534The \CFA string lets the user work at the level of just putting the right text into the right variables, with corresponding performance degradations reduced or eliminated.
    15221535
     
    15291542These tests use a \emph{corpus} of strings.
    15301543Their lengths are important; the specific characters occurring in them are immaterial.
    1531 In a result graph, a corpus's mean string length is often the independent variable shown on the X axis.
    1532 
     1544In a result graph, a corpus's mean string-length is often the independent variable on the x-axis.
    15331545When a corpus contains strings of different lengths, the lengths are drawn from a lognormal distribution.
    15341546Therefore, strings much longer than the mean occur less often and strings slightly shorter than the mean occur most often.
     
    15441556To ensure comparable results, a common memory allocator is used for \CFA and \CC.
    15451557\CFA runs the llheap allocator~\cite{Zulfiqar22}, which is also plugged into \CC.
     1558The llheap allocator is significantly better than the standard @glibc@ allocator.
    15461559
    15471560The operations being measured take dozens of nanoseconds, so a succession of many invocations is run and timed as a group.
     
    16361649
    16371650\VRef[Figure]{fig:string-graph-peq-cppemu} shows the resulting performance.
    1638 The two fresh (solid) lines and the two reuse (dash) lines are identical, except for lengths $\le$10, where the \CC SSO has a 40\% average and minimally 24\% advantage.
     1651The two fresh (solid spline lines) and the two reuse (dash spline lines) are identical, except for lengths $\le$10, where the \CC SSO has a 40\% average and minimally 24\% advantage.
    16391652The gap between the fresh and reuse lines is the removal of the dynamic memory allocates and reuse of prior storage, \eg 100M allocations for fresh \vs 100 allocations for reuse across all experiments.
    16401653While allocation reduction is huge, data copying dominates the cost, so the lines are still reasonably close together.
     
    16911704In earlier experiments, the choice of \CFA API among HL and LL had no impact on the functionality being tested.
    16921705Here, however, the @+@ operation, which returns its result by value, is only available in HL.
    1693 The \CFA @+@ number was obtained by inlining the HL implementation of @+@, which is done using LL's @+=@, into the test harness, while omitting the HL-inherent extra dynamic allocation.  The HL-upon-LL @+@ implementation, is:
    1694 \begin{cfa}
    1695 struct string {
    1696         string_res * inner;  // RAII manages malloc/free, simple ownership
     1706The \CFA @+=@ is obtained by inlining the HL implementation of @+@, which is done using LL's @+=@, into the test harness, while omitting the HL-inherent extra dynamic allocation.  The HL-upon-LL @+@ implementation, is:
     1707\begin{cquote}
     1708\setlength{\tabcolsep}{20pt}
     1709\begin{tabular}{@{}ll@{}}
     1710\begin{cfa}
     1711struct string {   // simple ownership
     1712        string_res * inner;  // RAII manages malloc/free
    16971713};
    16981714void ?+=?( string & s, string s2 ) {
    16991715        (*s.inner) += (*s2.inner);
    17001716}
     1717\end{cfa}
     1718&
     1719\begin{cfa}
    17011720string @?+?@( string lhs, string rhs ) {
    17021721        string ret = lhs;
     
    17041723        return ret;
    17051724}
    1706 \end{cfa}
     1725
     1726\end{cfa}
     1727\end{tabular}
     1728\end{cquote}
    17071729This @+@ implementation is also the goal implementation of @+@ once the HL/LL workaround is no longer needed.  Inlining the induced LL steps into the test harness gives:
    17081730\begin{cquote}
     
    17501772So again, \CFA helps users who just want to treat strings as values, and not think about the resource management under the covers.
    17511773
    1752 While not a design goal, and not graphed, \CFA in STL-emulation mode outperformed STL in this case.
    1753 User-managed allocation reuse did not affect either implementation in this case; only ``fresh'' results are shown.
     1774\PAB{Something is wrong with these sentences: While not a design goal, and not graphed, \CFA in STL-emulation mode outperformed STL in this case.
     1775User-managed allocation reuse did not affect either implementation in this case; only ``fresh'' results are shown.}
    17541776
    17551777
     
    17681790\end{cfa}
    17691791With implicit sharing active, \CFA treats this operation as normal and supported.
    1770 
    1771 Again, an HL-LL difference requires an LL mockup.  This time, the fact to integrate into the test harness is that LL does not directly support pass-by-value.
     1792Again, an HL-LL difference requires a mockup as LL does not directly support pass-by-value.
    17721793\begin{cquote}
    17731794\setlength{\tabcolsep}{20pt}
     
    17971818The goal (HL) version gives the modified test harness, with a single loop.
    17981819Each iteration uses a corpus item as the argument to the function call.
    1799 These corpus items were imported to the string heap before beginning the timed run.
     1820These corpus items are imported to the string heap before beginning the timed run.
    18001821
    18011822\begin{figure}
     
    18111832
    18121833\VRef[Figure]{fig:string-graph-pbv} shows the costs for calling a function that receives a string argument by value.
    1813 STL's performance worsens uniformly as string length increases, while \CFA has the same performance at all sizes.
    1814 Although the STL is better than \CFA until string length 10 because of the SSO.
     1834STL's performance worsens uniformly as string length increases, except for short strings due to SSO, while \CFA has the same performance at all sizes.
    18151835While improved, the \CFA cost to pass a string is still nontrivial.
    18161836The contributor is adding and removing the callee's string handle from the global list.
  • doc/theses/mike_brooks_MMath/uw-ethesis-frontpgs.tex

    r79ba50c r8614140  
    139139Often, the array is part of the programming language, while linked lists are built from (recursive) pointer types, and strings from arrays and/or linked lists.
    140140For all three types, languages and/or their libraries supply varying degrees of high-level mechanisms for manipulating these objects at the bulk and component levels, such as copying, slicing, extracting, and iterating among elements.
    141 Unfortunately, typical solutions for the the key types in C cause 60\%--70\% of the reported software vulnerabilities involving memory errors; 70\%--80\% of hacker attack vectors target these types.
     141Unfortunately, typical solutions for the these key types in C cause 60\%--70\% of the reported software vulnerabilities involving memory errors; 70\%--80\% of hacker attack-vectors target these types.
    142142Therefore, hardening these three C types goes a long way to make the majority of C programs safer.
    143143
  • libcfa/src/collections/array.hfa

    r79ba50c r8614140  
    6969        //    types like size_t.  So trying to overload on ptrdiff_t vs int works in 64-bit mode
    7070        //    but not in 32-bit mode.
    71         // -  Given bug of Trac #247, CFA gives sizeof expressions type unsigned long int, when it
    72         //    should give them type size_t.
    73         //
    74         //                          gcc -m32         cfa -m32 given bug         gcc -m64 (and cfa)
    75         // ptrdiff_t                int              int                        long int
    76         // size_t                   unsigned int     unsigned int               unsigned long int
    77         // typeof( sizeof(42) )     unsigned int     unsigned long int          unsigned long int
    78         // int                      int              int                        int
     71        //
     72        //                          cfa -m32 (and gcc)      cfa -m64 (and gcc)
     73        // ptrdiff_t                int                     long int
     74        // size_t                   unsigned int            unsigned long int
     75        // typeof( sizeof(42) )     unsigned int            unsigned long int
     76        // int                      int                     int
    7977        //
    8078        // So the solution must support types {zero_t, one_t, int, unsigned int, long int, unsigned long int}
     
    8381        // because assertion satisfaction requires types to match exacly.  Both higher-dimensional
    8482        // subscripting and operations on slices use asserted subscript operators.  The test case
    85         // array-container/array-sbscr-cases covers the combinations.  Mike beleives that commenting out
     83        // array-collections/array-sbscr-types covers the combinations.  Mike beleives that commenting out
    8684        // any of the current overloads leads to one of those cases failing, either on 64- or 32-bit.
    8785        // Mike is open to being shown a smaller set of overloads that still passes the test.
     86
    8887
    8988        static inline Timmed & ?[?]( arpk( N, S, Timmed, Tbase ) & a, zero_t ) {
     
    242241        return this[[ab0,ab1,ab2]][bc];
    243242}
     243
     244// Further form of -[-,-,-] that avoids using the trait system.
     245// Above overloads work for any type with (recursively valid) subscript operator,
     246// provided said subscript is passed as an assertion.
     247// Below works only on arpk variations but never passes its subscript though an assertion.
     248//
     249// When arpk implements the trait used above,
     250// the critical assertion is backed by a nontrivial thunk.
     251// There is no "thunk problem" (lifetime) issue, when used as shown in the test suite.
     252// But the optimizer has shown difficulty removing these thunks in cases where "it should,"
     253// i.e. when all user code is in one compilation unit.
     254// Not that every attempt at removing such a thunk fails; cases have been found going both ways.
     255// Cases have been found with unnecessary bound-checks removed successfully,
     256// on user code written against the overloads below,
     257// but where these bound checks (which occur within `call`ed thunks) are not removed,
     258// on user code written against the overloads above.
     259//
     260// The overloads below provide specializations of the above
     261// that are a little harder to use than the ones above,
     262// but where array API erasure has been seen to be more effective.
     263// Note that the style below does not appeal to a case where thunk inlining is more effective;
     264// rather, it simply does not rely on thunks in the first place.
     265//
     266// Both usage styles are shown in test array-md-sbscr-cases#numSubscrTypeCompatibility,
     267// with the more general one above being "high abstraction,"
     268// and the more performant one below being "mid abstraction" and "low abstraction."
     269//
     270// A breadth of index types is not given here (providing -[size_t,size_t,...] only)
     271// because these declarations are not feeding a trait, so safe implicit arithmetic conversion kiks in.
     272// Even so, there may still be an un-met need for accepting
     273// either ptrdiff_t or size_t (signed or unsigned)
     274// because Mike has seen the optimizer resist removing bound checks when sign-conversion is in play.
     275// "Only size_t" is meeting today's need
     276// and no solution is known that avoids 2^D overloads for D dimensions
     277// while offering multiple subscript types and staying assertion-free.
     278//
     279// This approach, of avoiding traits entirely, is likely incompatible with the original desire
     280// to have one recursive multidimensional subscript operator (TRY_BROKEN_DESIRED_MD_SUBSCRIPT).
     281// To make a single declaration work,
     282// we would probably have to get better at coaxing the optimizer into inlining thunks.
     283
     284forall( [N2], S2*, [N1], S1*, Timmed1, Tbase )
     285static inline Timmed1 & ?[?]( arpk( N2, S2, arpk( N1, S1, Timmed1, Tbase ), Tbase ) & this, size_t ix2, size_t ix1 ) {
     286        return this[ix2][ix1];
     287}
     288
     289forall( [N3], S3*, [N2], S2*, [N1], S1*, Timmed1, Tbase )
     290static inline Timmed1 & ?[?]( arpk( N3, S3, arpk( N2, S2, arpk( N1, S1, Timmed1, Tbase ), Tbase ), Tbase ) & this, size_t ix3, size_t ix2, size_t ix1 ) {
     291        return this[ix3][ix2][ix1];
     292}
     293
     294forall( [N4], S4*, [N3], S3*, [N2], S2*, [N1], S1*, Timmed1, Tbase )
     295static inline Timmed1 & ?[?]( arpk( N4, S4, arpk( N3, S3, arpk( N2, S2, arpk( N1, S1, Timmed1, Tbase ), Tbase ), Tbase ), Tbase ) & this, size_t ix4, size_t ix3, size_t ix2, size_t ix1 ) {
     296        return this[ix4][ix3][ix2][ix1];
     297}
     298
     299
    244300
    245301#endif
  • tests/array-collections/array-md-sbscr-cases.cfa

    r79ba50c r8614140  
    231231}
    232232
     233// common function body, working on parameter wxyz, but for wxyz being different types
     234#define CHECK_NUM_SUBSCR_TYPE_COMPAT                                         \
     235    valExpected = getMagicNumber(2, 3, 4, 5);                                \
     236    assert(( wxyz[2] [3] [4] [5] == valExpected ));                          \
     237    assert(( wxyz[2,  3] [4] [5] == valExpected ));                          \
     238    assert(( wxyz[2] [3,  4] [5] == valExpected ));                          \
     239    assert(( wxyz[2] [3] [4,  5] == valExpected ));                          \
     240    assert(( wxyz[2,  3,  4] [5] == valExpected ));                          \
     241    assert(( wxyz[2] [3,  4,  5] == valExpected ));                          \
     242    assert(( wxyz[2,  3,  4,  5] == valExpected ));                          \
     243    for ( i; Nw ) {                                                          \
     244        assert(( wxyz[ i, 3, 4, 5 ] == getMagicNumber(i, 3, 4, 5) ));        \
     245    }                                                                        \
     246    for ( i; Nx ) {                                                          \
     247        assert(( wxyz[ 2, i, 4, 5 ] == getMagicNumber(2, i, 4, 5) ));        \
     248    }                                                                        \
     249    for ( i; Ny ) {                                                          \
     250        assert(( wxyz[ 2, 3, i, 5 ] == getMagicNumber(2, 3, i, 5) ));        \
     251    }                                                                        \
     252    for ( i; Nz ) {                                                          \
     253        assert(( wxyz[ 2, 3, 4, i ] == getMagicNumber(2, 3, 4, i) ));        \
     254    }
     255#define CHECK_NUM_SUBSCR_TYPE_COMPAT_ADDENDUM_RESHAPE                        \
     256    for ( i; Nw ) {                                                          \
     257        assert(( wxyz[ i, all, 4, 5 ][3] == getMagicNumber(i, 3, 4, 5) ));   \
     258    }                                                                        \
     259    for ( i; Nw ) {                                                          \
     260        assert(( wxyz[ all, 3, 4, 5 ][i] == getMagicNumber(i, 3, 4, 5) ));   \
     261    }
     262
     263// Low abstraction: simple declaration, cannot send a slice, can make a slice, runs fast
     264forall( [Nw], [Nx], [Ny], [Nz] )
     265void test_numSubscrTypeCompatibility_lo( array( float, Nw, Nx, Ny, Nz ) & wxyz ) {
     266    CHECK_NUM_SUBSCR_TYPE_COMPAT
     267    CHECK_NUM_SUBSCR_TYPE_COMPAT_ADDENDUM_RESHAPE
     268}
     269
     270// Medium abstraction: complex declaration, can send or make a slice, runs fast
     271forall( [Nw], Sw*
     272      , [Nx], Sx*
     273      , [Ny], Sy*
     274      , [Nz], Sz* )
     275void test_numSubscrTypeCompatibility_mid(
     276        arpk( Nw, Sw,
     277        arpk( Nx, Sx,
     278        arpk( Ny, Sy,
     279        arpk( Nz, Sz, float, float)
     280                           , float)
     281                           , float)
     282                           , float) & wxyz
     283    ) {
     284    CHECK_NUM_SUBSCR_TYPE_COMPAT
     285    CHECK_NUM_SUBSCR_TYPE_COMPAT_ADDENDUM_RESHAPE
     286}
     287
     288// High abstraction: mid-complexity declaration, can send a slice or a non-arpk, cannot make a slice, may not run fast
     289forall( [Nw], Awxyz &
     290      , [Nx], Axyz &
     291      , [Ny], Ayz &
     292      , [Nz], Az &
     293      | ar( Awxyz, Axyz, Nw )
     294      | ar( Axyz, Ayz, Nx )
     295      | ar( Ayz, Az, Ny )
     296      | ar( Az, float, Nz ) )
     297void test_numSubscrTypeCompatibility_hi( Awxyz & wxyz ) {
     298    CHECK_NUM_SUBSCR_TYPE_COMPAT
     299}
     300
    233301forall( [Nw], [Nx], [Ny], [Nz] )
    234302void test_numSubscrTypeCompatibility( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
     
    237305    fillHelloData(wxyz);
    238306
    239     valExpected = getMagicNumber(2, 3, 4, 5);
    240     assert(( wxyz [2] [3] [4] [5]  == valExpected ));
    241     assert(( wxyz[2,  3][4] [5]  == valExpected ));
    242     assert(( wxyz [2][3,  4][5]  == valExpected ));
    243     assert(( wxyz [2] [3][4,  5] == valExpected ));
    244     assert(( wxyz[2,  3,  4][5]  == valExpected ));
    245     assert(( wxyz [2][3,  4,  5] == valExpected ));
    246     assert(( wxyz[2,  3,  4,  5] == valExpected ));
    247 
    248     for ( i; Nw ) {
    249         assert(( wxyz[ i, 3, 4, 5 ] == getMagicNumber(i, 3, 4, 5) ));
    250     }
    251 
    252     for ( i; Nx ) {
    253         assert(( wxyz[ 2, i, 4, 5 ] == getMagicNumber(2, i, 4, 5) ));
    254     }
    255 
    256     for ( i; Ny ) {
    257         assert(( wxyz[ 2, 3, i, 5 ] == getMagicNumber(2, 3, i, 5) ));
    258     }
    259 
    260     for ( i; Nz ) {
    261         assert(( wxyz[ 2, 3, 4, i ] == getMagicNumber(2, 3, 4, i) ));
    262     }
    263 
    264     for ( i; Nw ) {
    265         assert(( wxyz[ i, all, 4, 5 ][3] == getMagicNumber(i, 3, 4, 5) ));
    266     }
    267 
    268     for ( i; Nw ) {
    269         assert(( wxyz[ all, 3, 4, 5 ][i] == getMagicNumber(i, 3, 4, 5) ));
    270     }
     307    test_numSubscrTypeCompatibility_lo ( wxyz );
     308    test_numSubscrTypeCompatibility_mid( wxyz );
     309    test_numSubscrTypeCompatibility_hi ( wxyz );
    271310}
    272311
Note: See TracChangeset for help on using the changeset viewer.