Changeset c7ad609


Ignore:
Timestamp:
Feb 18, 2018, 12:11:24 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
23a1eb7b
Parents:
c5c4096
Message:

wordsmithing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/general/Paper.tex

    rc5c4096 rc7ad609  
    105105
    106106\newenvironment{cquote}{%
    107         \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%
     107        \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=3pt\parsep=0pt\leftmargin=\parindentlnth\rightmargin\leftmargin}%
    108108        \item\relax
    109109}{%
     
    10781078
    10791079Both labelled @continue@ and @break@ are a @goto@ restricted in the following ways:
    1080 \begin{itemize}
     1080\begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]
    10811081\item
    10821082They cannot create a loop, which means only the looping constructs cause looping.
     
    11591159}
    11601160\end{cfa}
    1161 \CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses, but no statements.
     1161\CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
    11621162\CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
    11631163
     
    12551255        int i;
    12561256        double d;
    1257         int f() {                                                               $\C{// implicit "this" parameter}$
     1257        int f() {                                                               $\C{// implicit ``this'' aggregate}$
    12581258                `this->`c; `this->`i; `this->`d;        $\C{// access containing fields}$
    12591259        }
     
    13201320\begin{cfa}
    13211321void ?{}( S & s, int i ) with ( s ) {           $\C{// constructor}$
    1322         `s.i = i;` j = 3; m = 5.5;
     1322        `s.i = i;`  j = 3;  m = 5.5;                    $\C{// initialize fields}$
    13231323}
    13241324\end{cfa}
     
    13641364\section{Declarations}
    13651365
    1366 It is important that \CFA subjectively ``feel like'' C to user programmers.
     1366It is important that \CFA subjectively ``feel like'' C to programmers.
    13671367An important part of this subjective feel is maintaining C's procedural paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust.
    13681368Maintaining this procedural paradigm means that C coding-patterns remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development.
     
    13981398
    13991399\CFA provides its own type, variable and routine declarations, using a different syntax.
    1400 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
     1400The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right.
    14011401The qualifiers have the same meaning but are ordered left to right to specify a variable's type.
    14021402\begin{cquote}
    14031403\lstDeleteShortInline@%
    1404 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     1404\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
    14051405\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    14061406\begin{cfa}
     
    14141414int `(*`x2`)[5]`;
    14151415`int (*`f( int p )`)[5]`;
     1416\end{cfa}
     1417&
     1418\begin{cfa}
     1419// array of 5 pointers to int
     1420// pointer to an array of 5 int
     1421// function returning pointer to an array of 5 int and taking an int
    14161422\end{cfa}
    14171423\end{tabular}
     
    14281434\begin{cfa}
    14291435`*` int x, y;
     1436int y;
    14301437\end{cfa}
    14311438&
    14321439\begin{cfa}
    14331440int `*`x, `*`y;
     1441
    14341442\end{cfa}
    14351443\end{tabular}
    14361444\lstMakeShortInline@%
    14371445\end{cquote}
    1438 The downside of this semantics is the need to separate regular and pointer declarations:
    1439 \begin{cquote}
    1440 \lstDeleteShortInline@%
    1441 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1442 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    1443 \begin{cfa}
    1444 `*` int x;
    1445 int y;
    1446 \end{cfa}
    1447 &
    1448 \begin{cfa}
    1449 int `*`x, y;
    1450 
    1451 \end{cfa}
    1452 \end{tabular}
    1453 \lstMakeShortInline@%
    1454 \end{cquote}
    1455 which is prescribing a safety benefit.
     1446The downside of the \CFA semantics is the need to separate regular and pointer declarations.
    14561447
    14571448\begin{comment}
     
    15611552&
    15621553\begin{cfa}
    1563 double foo1(), foo2( int ), foo3( double );
     1554double foo1( void ), foo2( int ), foo3( double );
    15641555\end{cfa}
    15651556\end{tabular}
     
    15931584a value that does not have a corresponding address is called a \newterm{rvalue} (for ``right-hand value''), while a value that does have an address is called a \newterm{lvalue} (for ``left-hand value'').
    15941585For example, in @int x; x = 42;@ the variable expression @x@ on the left-hand-side of the assignment is a lvalue, while the constant expression @42@ on the right-hand-side of the assignment is a rvalue.
    1595 Despite the nomenclature of ``left-hand'' and ``right-hand'', an expression's classification as lvalue or rvalue is entirely dependent on whether it has an address or not; in imperative programming, the address of a value is used for both reading and writing (mutating) a value, and as such lvalues can be converted to rvalues and read from, but rvalues cannot be mutated because they lack a location to store the updated value.
     1586Despite the nomenclature of ``left-hand'' and ``right-hand'', an expression's classification as lvalue or rvalue is entirely dependent on whether it has an address or not; in imperative programming, the address of a value is used for both reading and writing (mutating) a value, and as such, lvalues can be converted to rvalues and read from, but rvalues cannot be mutated because they lack a location to store the updated value.
    15961587
    15971588Within a lexical scope, lvalue expressions have an \newterm{address interpretation} for writing a value or a \newterm{value interpretation} to read a value.
    15981589For example, in @x = y@, @x@ has an address interpretation, while @y@ has a value interpretation.
    1599 Though this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \newterm{pointer types} to serve a similar purpose.
     1590While this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \newterm{pointer types} to serve a similar purpose.
    16001591In C, for any type @T@ there is a pointer type @T *@, the value of which is the address of a value of type @T@.
    16011592A pointer rvalue can be explicitly \newterm{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, while the rvalue representing the address of a lvalue can be obtained with the address-of operator @&?@.
     
    16091600\end{cfa}
    16101601
    1611 Unfortunately, the dereference and address-of operators introduce a great deal of syntactic noise when dealing with pointed-to values rather than pointers, as well as the potential for subtle bugs.
    1612 For both brevity and clarity, it would be desirable to have the compiler figure out how to elide the dereference operators in a complex expression such as the assignment to @*p2@ above.
    1613 However, since C defines a number of forms of \newterm{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a user programmer may write one when they mean the other, and precluding any simple algorithm for elision of dereference operators.
    1614 To solve these problems, \CFA introduces reference types @T&@; a @T&@ has exactly the same value as a @T*@, but where the @T*@ takes the address interpretation by default, a @T&@ takes the value interpretation by default, as below:
     1602Unfortunately, the dereference and address-of operators introduce a great deal of syntactic noise when dealing with pointed-to values rather than pointers, as well as the potential for subtle bugs because of pointer arithmetic.
     1603For both brevity and clarity, it is desirable for the compiler to figure out how to elide the dereference operators in a complex expression such as the assignment to @*p2@ above.
     1604However, since C defines a number of forms of \newterm{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a programmer may write one when they mean the other, and precluding any simple algorithm for elision of dereference operators.
     1605To solve these problems, \CFA introduces reference types @T &@;
     1606a @T &@ has exactly the same value as a @T *@, but where the @T *@ takes the address interpretation by default, a @T &@ takes the value interpretation by default, as below:
    16151607
    16161608\begin{cfa}
     
    16191611&r2 = &y;  $\C{// r2 points to y}$
    16201612&&r3 = &&r1;  $\C{// r3 points to r2}$
    1621 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15);  $\C{// implicit dereferencing}$
     1613r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15);       $\C{// implicit dereferencing}$
    16221614\end{cfa}
    16231615
    16241616Except for auto-dereferencing by the compiler, this reference example is exactly the same as the previous pointer example.
    1625 Hence, a reference behaves like a variable name -- an lvalue expression which is interpreted as a value, but also has the type system track the address of that value.
     1617Hence, a reference behaves like a variable name -- an lvalue expression which is interpreted as a value -- but also has the type system track the address of that value.
    16261618One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in the reference variable declaration, so the previous example implicitly acts like:
    16271619
     
    16301622\end{cfa}
    16311623
    1632 References in \CFA are similar to those in \CC, but with a couple important improvements, both of which can be seen in the example above.
    1633 Firstly, \CFA does not forbid references to references, unlike \CC.
     1624References in \CFA are similar to those in \CC, with important improvements, which can be seen in the example above.
     1625Firstly, \CFA does not forbid references to references.
    16341626This provides a much more orthogonal design for library implementors, obviating the need for workarounds such as @std::reference_wrapper@.
    1635 
    1636 Secondly, unlike the references in \CC which always point to a fixed address, \CFA references are rebindable.
    1637 This allows \CFA references to be default-initialized (\eg to a null pointer), and also to point to different addresses throughout their lifetime.
    1638 This rebinding is accomplished without adding any new syntax to \CFA, but simply by extending the existing semantics of the address-of operator in C.
     1627Secondly, \CFA references are rebindable, whereas \CC references have a fixed address.
     1628\newsavebox{\LstBox}
     1629\begin{lrbox}{\LstBox}
     1630\lstset{basicstyle=\footnotesize\linespread{0.9}\sf}
     1631\begin{cfa}
     1632int & r = *new( int );
     1633...
     1634delete &r;
     1635r += 1;                 // undefined reference
     1636\end{cfa}
     1637\end{lrbox}
     1638Rebinding allows \CFA references to be default-initialized (\eg to a null pointer\footnote{
     1639While effort has been put into non-null reference checking in \CC, the exercise seems moot for any non-managed languages, given that it only handles one of many different error situations:
     1640\begin{cquote}
     1641\usebox{\LstBox}
     1642\end{cquote}
     1643}%
     1644) and point to different addresses throughout their lifetime, like pointers.
     1645Rebinding is accomplished by extending the existing syntax and semantics of the address-of operator in C.
    16391646
    16401647In C, the address of a lvalue is always a rvalue, as in general that address is not stored anywhere in memory, and does not itself have an address.
    1641 In \CFA, the address of a @T&@ is a lvalue @T*@, as the address of the underlying @T@ is stored in the reference, and can thus be mutated there.
     1648In \CFA, the address of a @T &@ is a lvalue @T *@, as the address of the underlying @T@ is stored in the reference, and can thus be mutated there.
    16421649The result of this rule is that any reference can be rebound using the existing pointer assignment semantics by assigning a compatible pointer into the address of the reference, \eg @&r1 = &x;@ above.
    1643 This rebinding can occur to an arbitrary depth of reference nesting; loosely speaking, nested address-of operators will produce an lvalue nested pointer up to as deep as the reference they're applied to.
     1650This rebinding occurs to an arbitrary depth of reference nesting;
     1651loosely speaking, nested address-of operators produce a nested lvalue pointer up to the depth of the reference.
    16441652These explicit address-of operators can be thought of as ``cancelling out'' the implicit dereference operators, \eg @(&`*`)r1 = &x@ or @(&(&`*`)`*`)r3 = &(&`*`)r1@ or even @(&`*`)r2 = (&`*`)`*`r3@ for @&r2 = &r3@.
    16451653More precisely:
    1646 \begin{itemize}
    1647         \item
    1648         if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) than @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols).
     1654\begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]
     1655\item
     1656if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) than @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols).
    16491657       
    1650         \item
    1651         if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T `*`&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\ \ie @T@ pointer with $l$ references (@&@ symbols).
     1658\item
     1659if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T `*`&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\ \ie @T@ pointer with $l$ references (@&@ symbols).
    16521660\end{itemize}
    1653 Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them in user code can be made based solely on convenience.
     1661Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them is made solely on convenience, \eg many pointer or value accesses.
    16541662
    16551663By analogy to pointers, \CFA references also allow cv-qualifiers such as @const@:
    1656 
    1657 \begin{cfa}
    1658 const int cx = 5;               $\C{// cannot change cx}$
    1659 const int & cr = cx;    $\C{// cannot change cr's referred value}$
    1660 &cr = &cx;                              $\C{// rebinding cr allowed}$
    1661 cr = 7;                                 $\C{// ERROR, cannot change cr}$
    1662 int & const rc = x;             $\C{// must be initialized, like in \CC}$
    1663 &rc = &x;                               $\C{// ERROR, cannot rebind rc}$
    1664 rc = 7;                                 $\C{// x now equal to 7}$
    1665 \end{cfa}
    1666 
     1664\begin{cfa}
     1665const int cx = 5;                                                       $\C{// cannot change cx}$
     1666const int & cr = cx;                                            $\C{// cannot change cr's referred value}$
     1667&cr = &cx;                                                                      $\C{// rebinding cr allowed}$
     1668cr = 7;                                                                         $\C{// ERROR, cannot change cr}$
     1669int & const rc = x;                                                     $\C{// must be initialized, like in \CC}$
     1670&rc = &x;                                                                       $\C{// ERROR, cannot rebind rc}$
     1671rc = 7;                                                                         $\C{// x now equal to 7}$
     1672\end{cfa}
    16671673Given that a reference is meant to represent a lvalue, \CFA provides some syntactic shortcuts when initializing references.
    16681674There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, and return/temporary binding.
    1669 In each of these contexts, the address-of operator on the target lvalue may (in fact, must) be elided.
    1670 The syntactic motivation for this is clearest when considering overloaded operator-assignment, \eg @int ?+=?(int &, int)@; given @int x, y@, the expected call syntax is @x += y@, not @&x += y@.
    1671 
    1672 More generally, this initialization of references from lvalues rather than pointers is an instance of a ``lvalue-to-reference'' conversion rather than an elision of the address-of operator; this conversion can actually be used in any context in \CFA an implicit conversion would be allowed.
     1675In each of these contexts, the address-of operator on the target lvalue is elided.
     1676The syntactic motivation is clearest when considering overloaded operator-assignment, \eg @int ?+=?(int &, int)@; given @int x, y@, the expected call syntax is @x += y@, not @&x += y@.
     1677
     1678More generally, this initialization of references from lvalues rather than pointers is an instance of a ``lvalue-to-reference'' conversion rather than an elision of the address-of operator;
     1679this conversion is used in any context in \CFA where an implicit conversion is allowed.
    16731680Similarly, use of a the value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, analogous to the @T *@ to @const T *@ conversion in standard C.
    16741681The final reference conversion included in \CFA is ``rvalue-to-reference'' conversion, implemented by means of an implicit temporary.
    16751682When an rvalue is used to initialize a reference, it is instead used to initialize a hidden temporary value with the same lexical scope as the reference, and the reference is initialized to the address of this temporary.
     1683\begin{cfa}
     1684struct S { double x, y; };
     1685int i, j;
     1686void f( int & i, int & j, S & s, int v[] );
     1687f( 3, i + j, (S){ 1.0, 7.0 }, (int [3]){ 1, 2, 3 } );   $\C{// pass rvalue to lvalue \(\Rightarrow\) implicit temporary}$
     1688\end{cfa}
    16761689This allows complex values to be succinctly and efficiently passed to functions, without the syntactic overhead of explicit definition of a temporary variable or the runtime cost of pass-by-value.
    16771690\CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \newterm{const hell} problem, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers.
     
    16801693\subsection{Constructors and Destructors}
    16811694
    1682 One of the strengths of C is the control over memory management it gives programmers, allowing resource release to be more consistent and precisely timed than is possible with garbage-collected memory management.
    1683 However, this manual approach to memory management is often verbose, and it is useful to manage resources other than memory (\eg file handles) using the same mechanism as memory.
    1684 \CC is well-known for an approach to manual memory management that addresses both these issues, Resource Aquisition Is Initialization (RAII), implemented by means of special \newterm{constructor} and \newterm{destructor} functions; we have implemented a similar feature in \CFA.
    1685 While RAII is a common feature of object-oriented programming languages, its inclusion in \CFA does not violate the design principle that \CFA retain the same procedural paradigm as C.
    1686 In particular, \CFA does not implement class-based encapsulation: neither the constructor nor any other function has privileged access to the implementation details of a type, except through the translation-unit-scope method of opaque structs provided by C.
    1687 
    1688 In \CFA, a constructor is a function named @?{}@, while a destructor is a function named @^?{}@; like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @x{ ... };@ or @^x{};@.
    1689 Every constructor and destructor must have a return type of @void@, and its first parameter must have a reference type whose base type is the type of the object the function constructs or destructs.
    1690 This first parameter is informally called the @this@ parameter, as in many object-oriented languages, though a programmer may give it an arbitrary name.
    1691 Destructors must have exactly one parameter, while constructors allow passing of zero or more additional arguments along with the @this@ parameter.
    1692 
    1693 \begin{cfa}
    1694 struct Array {
    1695         int * data;
    1696         int len;
     1695One of the strengths (and weaknesses) of C is control over memory management, allowing resource release to be more consistent and precisely timed than possible with garbage-collected memory-management.
     1696However, this manual approach is often verbose, furthermore it is useful to manage resources other than memory (\eg file handles) using the same mechanism as memory.
     1697\CC addresses these issues using Resource Aquisition Is Initialization (RAII), implemented by means of \newterm{constructor} and \newterm{destructor} functions;
     1698\CFA adopts constructors and destructors (and @finally@) to facilitate RAII.
     1699While constructors and destructors are a common feature of object-oriented programming-languages, they are independent capabilities allowing \CFA to retain a procedural paradigm.
     1700Specifically, \CFA constructors and destructors are denotes by name and first parameter-type versus name and nesting in an aggregate type.
     1701
     1702In \CFA, a constructor is named @?{}@ and a destructor is named @^?{}@;
     1703like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @x{ ... };@ or @^x{...};@.
     1704The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = `{` 2, 3 `}`@.
     1705The constructor and destructor have return type @void@ and a first parameter of reference to the object type to be constructed or destructs.
     1706While the first parameter is informally called the @this@ parameter, as in object-oriented languages, any variable name may be used.
     1707Both constructors and destructors allow additional parametes after the @this@ parameter for specifying values for initialization/de-initialization\footnote{Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not de-allocate.}.
     1708\begin{cfa}
     1709struct VLA {
     1710        int len, * data;
    16971711};
    1698 
    1699 void ?{}( Array& arr ) {
    1700         arr.len = 10;
    1701         arr.data = calloc( arr.len, sizeof(int) );
    1702 }
    1703 
    1704 void ^?{}( Array& arr ) {
    1705         free( arr.data );
    1706 }
    1707 
    1708 {
    1709         Array x;
    1710         `?{}(x);`       $\C{// implicitly compiler-generated}$
     1712void ?{}( VLA& vla ) with ( vla ) {                     $\C{// default constructor}$
     1713        len = 10;  data = calloc( len );
     1714}
     1715void ^?{}( VLA& vla ) {                                         $\C{// destructor}$
     1716        free( vla.data );
     1717}
     1718{       VLA x; `?{}(x);`                                                $\C{// compiler generated constructor call}$
    17111719        // ... use x
    1712         `^?{}(x);`      $\C{// implicitly compiler-generated}$
    1713 }
    1714 \end{cfa}
    1715 
    1716 In the example above, a \newterm{default constructor} (\ie one with no parameters besides the @this@ parameter) and destructor are defined for the @Array@ struct, a dynamic array of @int@.
    1717 @Array@ is an example of a \newterm{managed type} in \CFA, a type with a non-trivial constructor or destructor, or with a field of a managed type.
    1718 As in the example, all instances of managed types are implicitly constructed upon allocation, and destructed upon deallocation; this ensures proper initialization and cleanup of resources contained in managed types, in this case the @data@ array on the heap.
     1720`^?{}(x);` }                                                            $\C{// compiler generated desturctor call}$
     1721\end{cfa}
     1722@VLA@ is an example of a \newterm{managed type}\footnote{A managed type affects the runtime environment versus being self-contained.} in \CFA: a type requiring a non-trivial constructor or destructor, or with a field of a managed type.
     1723A managed types is implicitly constructed upon allocation, and destructed upon deallocation to ensure proper interaction of runtime resources, in this case the @data@ array in the heap.
    17191724The exact details of the placement of these implicit constructor and destructor calls are omitted here for brevity, the interested reader should consult \cite{Schluntz17}.
    17201725
    1721 Constructor calls are intended to seamlessly integrate with existing C initialization syntax, providing a simple and familiar syntax to veteran C programmers and allowing constructor calls to be inserted into legacy C code with minimal code changes.
    1722 As such, \CFA also provides syntax for \newterm{copy initialization} and \newterm{initialization parameters}:
    1723 
    1724 \begin{cfa}
    1725 void ?{}( Array& arr, Array other );
    1726 
    1727 void ?{}( Array& arr, int size, int fill );
    1728 
    1729 Array y = { 20, 0xDEADBEEF }, z = y;
     1726Constructor calls seamlessly integrate with existing C initialization syntax, providing a simple and familiar syntax to C programmers and allowing constructor calls to be inserted into legacy C code with minimal code changes.
     1727As such, \CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
     1728\begin{cfa}
     1729void ?{}( VLA & vla, int size, int fill );      $\C{// initialization}$
     1730void ?{}( VLA & vla, VLA other );                       $\C{// copy}$
     1731VLA y = { 20, 0xdeadbeef },  // initialization
     1732           z = y; // copy
    17301733\end{cfa}
    17311734
     
    17381741
    17391742\begin{cfa}
    1740 Array a, b;
     1743VLA a, b;
    17411744a{};                            $\C{// default construct}$
    17421745b{ a };                         $\C{// copy construct}$
     
    17591762In rare situations user programmers may not wish to have constructors and destructors called; in these cases, \CFA provides an ``escape hatch'' to not call them.
    17601763If a variable is initialized using the syntax \lstinline|S x @= {}| it will be an \newterm{unmanaged object}, and will not have constructors or destructors called.
    1761 Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg  \lstinline|Array a @= { 0, 0x0 }|, with the usual C initialization semantics.
     1764Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg  \lstinline|VLA a @= { 0, 0x0 }|, with the usual C initialization semantics.
    17621765In addition to the expressive power, \lstinline|@=| provides a simple path for migrating legacy C code to \CFA, by providing a mechanism to incrementally convert initializers; the \CFA design team decided to introduce a new syntax for this escape hatch because we believe that our RAII implementation will handle the vast majority of code in a desirable way, and we wished to maintain familiar syntax for this common case.
    17631766
     
    18451848In keeping with the general \CFA approach of adding features while respecting ``the C way'' of doing things, we have extended both C's polymorphic zero and typed literal syntax to interoperate with user-defined types, while maintaining a backwards-compatible semantics.
    18461849
     1850
    18471851\subsection{0/1}
    18481852
     
    18561860\CFA also includes a special type for @1@, @one_t@; like @zero_t@, @one_t@ has built-in implicit conversions to the various integral types so that @1@ maintains its expected semantics in legacy code.
    18571861The addition of @one_t@ allows generic algorithms to handle the unit value uniformly for types where that is meaningful.
    1858 \TODO{Make this sentence true} In particular, polymorphic functions in the \CFA prelude define @++x@ and @x++@ in terms of @x += 1@, allowing users to idiomatically define all forms of increment for a type @T@ by defining the single function @T& ?+=(T&, one_t)@; analogous overloads for the decrement operators are present as well.
     1862\TODO{Make this sentence true} In particular, polymorphic functions in the \CFA prelude define @++x@ and @x++@ in terms of @x += 1@, allowing users to idiomatically define all forms of increment for a type @T@ by defining the single function @T & ?+=(T &, one_t)@; analogous overloads for the decrement operators are present as well.
     1863
    18591864
    18601865\subsection{Units}
     
    20342039The following shows one example where \CFA \emph{extends} an existing standard C interface to reduce complexity and provide safety.
    20352040C/\Celeven provide a number of complex and overlapping storage-management operation to support the following capabilities:
    2036 \begin{description}[itemsep=2pt,parsep=0pt]
     2041\begin{description}[topsep=3pt,itemsep=2pt,parsep=0pt]
    20372042\item[fill]
    20382043after allocation the storage is filled with a specified character.
     
    20672072ip = alloc( ip, 2 * dim );
    20682073ip = alloc( ip, 4 * dim, fill );
    2069 
    2070 ip = align_alloc( 16 );
    2071 ip = align_alloc( 16, fill );
    2072 ip = align_alloc( 16, dim );
    2073 ip = align_alloc( 16, dim, fill );
    20742074\end{cfa}
    20752075&
     
    20812081ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
    20822082ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
    2083 
     2083\end{cfa}
     2084\end{tabular}
     2085\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     2086\begin{cfa}
     2087ip = align_alloc( 16 );
     2088ip = align_alloc( 16, fill );
     2089ip = align_alloc( 16, dim );
     2090ip = align_alloc( 16, dim, fill );
     2091\end{cfa}
     2092&
     2093\begin{cfa}
    20842094ip = memalign( 16, sizeof( int ) );
    20852095ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
     
    21982208The implicit separator character (space/blank) is a separator not a terminator.
    21992209The rules for implicitly adding the separator are:
    2200 \begin{itemize}[itemsep=2pt,parsep=0pt]
     2210\begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]
    22012211\item
    22022212A separator does not appear at the start or end of a line.
Note: See TracChangeset for help on using the changeset viewer.