Changeset 67fa9f9


Ignore:
Timestamp:
Jul 5, 2017, 10:50:22 AM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
0614d14
Parents:
11dbfe1 (diff), 307a732 (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:
7 added
1 deleted
65 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r11dbfe1 r67fa9f9  
    5454doc/user/pointer1.tex
    5555doc/user/pointer2.tex
     56doc/user/EHMHierarchy.tex
  • doc/LaTeXmacros/lstlang.sty

    r11dbfe1 r67fa9f9  
    88%% Created On       : Sat May 13 16:34:42 2017
    99%% Last Modified By : Peter A. Buhr
    10 %% Last Modified On : Fri May 26 12:47:09 2017
    11 %% Update Count     : 8
     10%% Last Modified On : Thu Jun 22 07:40:31 2017
     11%% Update Count     : 10
    1212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1313
     
    116116                _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex,
    117117                resume, suspend, thread, _Thread_local, yield},
     118        moredirectives={defined,include_next}%
    118119}
    119120
  • doc/generic_types/mail

    r11dbfe1 r67fa9f9  
    7878
    7979- OOPSLA'17 Submissions
     80
     81
     82
     83From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
     84Subject: [OOPSLA'17] Paper #20 "Generic and Tuple Types with Efficient..."
     85To: Peter Buhr <pabuhr@uwaterloo.ca>
     86Cc: jonathan.aldrich@cs.cmu.edu
     87Reply-To: jonathan.aldrich@cs.cmu.edu
     88Date: Wed,  7 Jun 2017 13:33:40 +0000 (UTC)
     89
     90Dear Peter Buhr,
     91
     92The author response period for OOPSLA has started, and will continue until
     93the end of June 10th (Anywhere on Earth).  No email with a snapshot of your
     94reviews will be sent: you can see the live version of reviews (including
     95current updates) on the HotCRP system (links at the bottom).
     96
     97An author response should aim to:
     98 -correct reviewers' mistakes or misunderstandings
     99 -offer new information only when this addresses reviewers' concerns (e.g.,
     100"I wonder if A might work better...";  "we tried that, but...")
     101 -answer explicit questions by the reviewers. The key questions will be in a
     102designated "Questions for Author Response" entry of a review.
     103
     104Please keep in mind that an author response is *not* a "rebuttal". You are
     105not rebutting an opponent's arguments with your own, in front of an
     106audience that weighs both sets of arguments. Instead, your audience is the
     107same reviewers who offered the comments in the first place, and their
     108subjective weighing of different factors is very unlikely to change.
     109
     110During author response, please keep in mind that the reviewers are still
     111unaware of author identity. If you need to refer to author-identifying
     112information during your response, the ideal course of action is to place it
     113at an external location and include a URL, with an explicit warning (e.g.,
     114"WARNING: following this link will reveal author identity").
     115
     116As with all external resources, your response should be self-contained,
     117without consulting them. That is, the author-visible external URL is just
     118evidence, but the claim that this evidence supports should be clear in the
     119response text. For instance:
     120"we have received public feedback from the developers of X that confirm the
     121issue [supporting URL] (WARNING: following this link will reveal author
     122identity)"
     123
     124Your paper's access information is below:
     125
     126       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
     127  Paper site: https://oopsla17.hotcrp.com/paper/20
     128
     129Use the link below to sign in to the site.
     130
     131https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca
     132
     133Please contact me <jonathan.aldrich@cs.cmu.edu> with any questions or
     134concerns.
     135
     136Best Regards and wishes for a constructive response,
     137
     138Jonathan Aldrich
     139
     140
     141
     142From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
     143Subject: [OOPSLA'17] Paper #20 "Generic and Tuple Types with Efficient..."
     144To: Peter Buhr <pabuhr@uwaterloo.ca>
     145Cc: jonathan.aldrich@cs.cmu.edu
     146Reply-To: jonathan.aldrich@cs.cmu.edu
     147Date: Tue, 20 Jun 2017 00:33:10 +0000 (UTC)
     148
     149Dear Peter Buhr,
     150
     151I regret to inform you that your submission to OOPSLA'17 listed below has not
     152been selected for the second phase of the review process. I understand this is
     153not welcome news but selection was very competitive: 157 of the 223 papers
     154submitted did not advance to the second phase. For several of these, there was
     155a clear impression that in the future they can evolve into some of the
     156strongest results of our community.
     157
     158       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
     159  Paper site: https://oopsla17.hotcrp.com/paper/20
     160  Login link: https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca
     161
     162Below you will find reviews, as well as author-visible comments--the latter may
     163include further communication. I hope you will find the reviewers' feedback
     164useful.
     165
     166Best Regards,
     167
     168- Jonathan Aldrich <jonathan.aldrich@cs.cmu.edu>, for OOPSLA 2017
     169Submissions
     170
     171
     172
     173===========================================================================
     174                           OOPSLA'17 Review #20A
     175---------------------------------------------------------------------------
     176 Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
     177---------------------------------------------------------------------------
     178
     179                      Overall merit: C. Weak paper, though I will not fight
     180                                        strongly against it
     181                         Confidence: X. I am an expert in this area
     182
     183                         ===== Paper summary =====
     184
     185This presents an extension of the C programming language that tries to preserve the character of the existing language, while adding tuples and generics. Unlike C++ templates, generics preserve separate compilation. Types are represented at runtime, if needed, by size and alignment values, along with pointers to the code for any needed operators. A microbenchmark performance comparison is provided.
     186
     187                      ===== Comments for author =====
     188
     189This is an interesting extension to C, that may be of interest to some C programmers. It generally seems to be fairly well engineered, and mostly respects C's design goals.
     190
     191Unfortunately, there have been enough proposals for extended C dialects that this sort of design is tough to sell. And I don't think the evaluation really went far enough to make that case.
     192
     193The ideas in the paper don't appear to be fundamentally new. The idea of passing types as runtime objects has certainly been explored before. An additional ancient reference is http://dl.acm.org/citation.cfm?doid=13310.13330.
     194
     195There seems to be a new idea of minimally describing types using alignment and size attributes instead of (?) pointers to assignment operators and the like. But this scheme is not very well described. Notably, it is not clear how, say, a struct with atomic field or bit-fields would be described.
     196
     197I wasn't quite clear on the extent to which operator overloading is supported. The MAX example appears to me like it would be quite controversial among C programmers.
     198
     199It is not obvious that type inference here always converges. An outline of the algorithm would be useful.
     200
     201Above all, this needs experience results from a more complete implementation.
     202
     203Details:
     204
     205Relying on TIOBE here seems a bit dubious. Since it counts web pages, and C isn't exactly new and hot, it may actually understate your case.
     206
     207The print example seems a little simplistic, since it's not clear how it handles formatting.
     208
     209"does not using the return type"
     210
     211              ===== Questions for authors’ response =====
     212
     213How are atomics, volatile, and bit-fields in structs handled?
     214
     215===========================================================================
     216                           OOPSLA'17 Review #20B
     217---------------------------------------------------------------------------
     218 Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
     219---------------------------------------------------------------------------
     220
     221                      Overall merit: D. Reject
     222                         Confidence: X. I am an expert in this area
     223
     224                         ===== Paper summary =====
     225
     226The authors present an extension to C, adding universal polymorphism and tuples. These features are described in prose. There is an implementation, though this is not described in depth in the paper. There is a benchmark evaluation.
     227
     228                      ===== Comments for author =====
     229
     230The paper is well-written and the concepts explained well. It is nice to see work in the low-level/C space - I believe that it is an area that has not been well-served by the OOPSLA community. My concerns with the paper are that the contribution is rather small and the concepts are not well-evaluated; specifically this is a language design paper and there is no attempt to evaluate the actual language design.
     231
     232While it is reasonable to describe only a couple of features in a paper, I would then expect a detailed description of the implementation and/or a formalism with proven safety properties and a thorough evaluation of the design. For a paper which only describes the design of a language the bar is higher than two features - for example, a description of a 'large' language such as D or Rust, even then I would expect a stronger evaluation.
     233
     234## On the design of C-forall
     235
     236There are some interesting points in the design of generics, notably the otype/dtype distinction. The design seems reasonable and follows what I would expect from other languages. The design for tuples is more unusual - the usual design of simple anonymous records with anonymous fields is extended with a mix of 'spread'ing, variadics, and implicit conversions. Importantly, the authors neither justify nor evaluate this departure - that is a severe omission for this paper. Furthermore, the only in-depth description of the implementation in the paper concerns tuples, and it seems to me that this is only interesting because of the unusual design - further reason for justifying it.
     237
     238## Evaluation
     239
     240The paper evaluates the implementation of C-forall with (effectively) a single micro-benchmark. That benchmark seems to show that C-forall performs worse than C++ on every measure, but this is not really discussed.
     241
     242A better performance evaluation would consist of multiple tests, both micro-benchmarks and realistic code and would test C-forall compared to alternatives (D, Rust, Go, etc.) not just C/C++.
     243
     244However, performance is not the really interesting thing to test here. The authors propose a new language and while performance is an important consideration for systems languages, it is far from the most important. I would like to see the usability of the language tested with user studies of different kinds (various levels of skill-level and coding scenarios). The authors could also use case studies or programming idioms to compare programming in C-forall vs the alternatives (again, comparing with D, Rust, etc. is more interesting to me than C).
     245
     246Finally, in designing C-forall, the authors make several assumptions about why C programmers use C. These should be backed up either with evaluation or citation. Statements in the paper certainly do not reflect my experience discussing language design with C programmers, and I would like to see them verified.
     247
     248
     249## Related work
     250
     251The related work section is broad and gives good descriptions of other languages. However, the comparisons between languages focus more on the high-level goals of the language. It would be more interesting to focus on the details of the languages - the comparisons between Cyclone, C++, Java, and C-forall generics are good, I would like to see more of this with D and Rust, which are the more modern alternatives to C-forall (for example, Rust's notion of Sized and ?Sized types seems similar to otypes/dtypes).
     252
     253The related work is really missing any discussion of why the C-forall design choices are better than other languages. To clarify, I mean the specific design of generics and tuples, c.f., the suitability of the language in general because of garbage collection or learning difficulties.
     254
     255===========================================================================
     256                           OOPSLA'17 Review #20C
     257---------------------------------------------------------------------------
     258 Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
     259---------------------------------------------------------------------------
     260
     261                      Overall merit: D. Reject
     262                         Confidence: Z. I am not an expert; my evaluation
     263                                        is that of an informed outsider
     264
     265                         ===== Paper summary =====
     266
     267The paper presents two language features of "Cforall": generics and tuples.
     268
     269                      ===== Comments for author =====
     270
     271The authors really need to talk about C++ as early as possible IMHO. That's the first thing that came to mind when reading the abstract: how is this different from C++?
     272
     273Comparison with C++:
     274The main difference with C++ seems to be that Cforall favors separate compilation at the expense of runtime overhead while C++ systematically avoids any runtime overhead (at the expense of slow compilation times). C++ approach makes more sense IMHO. While it's true that people where using C for almost everything 30 years ago, that is just not true anymore. Most people writing C today are doing system programming, otherwise there would be using a higher level programming language (C#, Java etc ...).
     275Now, when doing system programming, one needs very fine grain control over the resources: memory layout, etc ...
     276It is pretty clear to me that the people writing that kind of code will favor generics that do not cost any overhead at runtime, otherwise they would be writing Java in the first place.
     277The authors need to better justify the runtime overhead, or give escape hatches for those who don't want to pay that cost at runtime.
     278They very often go back to the benefit of separate compilation, but that's not enough IMHO. Here is a proposal: why not have 2 modes, one called debug mode, used while developing the code, that would compile generics with a runtime overhead. Another, called production, that would unfold the world like C++ does?
     279
     280About Tuples:
     281The section about tuples is too long. I would have spent more time explaining generics.
     282
     283Feedback:
     284"This installation base"
     285Unclear what you mean by that.
     286
     287"Prior projects ... but failed ..."
     288Hummm ... What about C++.
     289
     290"... object-oriented or functional programming with garbage collection ..."
     291You are really mixing apples and oranges here. Many C programmers have nothing agains object-oriented features, not even functional programming (C++ 11 adds
     292a bunch of features proving my point), but it's clear that most of them feel very strongly against automated garbage collection.
     293
     294"In many cases, C++ is often ..."
     295This sentence feels like it is coming out of nowhere.
     296
     297"... the polymorphic runtime-cost ..."
     298Is there any way to avoid that overhead? It's true it will make the compiler faster, but there are cases where the user might not want to pay for
     299the overhead at runtime. Is there a way to force the compiler to specialize the code?
     300
     301"... to write a type-safe Cforall wrapper malloc based ..."
     302That cannot be true in general. Malloc produces a pointer (of any type), given an integer (the size).
     303It looks like Cforall is assuming that the integer is the result of a call to sizeof (a good practice in C).
     304However, if that's the case, it should be explained.
     305
     306"... allows variable overloading ..."
     307How are conflict resolved? In other words, what happens when two variables could be used?
     308
     309"... reuses the generated structure declarations where appropriate."
     310This is too vague.
     311
     312"... have multiple outcomes, some exceptional."
     313Humm, I would say these two things are distinct. Let's just way that this way of presenting things is strange, I woulds ay that a function can either
     314return one or multiple values or throw an exception. Not that some of the values returned are "exceptional".
     315
     316"The type-resolver ..."
     317What's that? Type-checker? Type-inference?
     318
     319"... applies C conversions."
     320Noooo! That's exactly what leads to very subtle bugs. Is there any way to stop those conversions from happening?
     321
     322"The minimal cost ..."
     323In what regard? Runtime cost? How does the "resolver" know how expensive the conversions are?
     324
     325"z = 10 // mass assignments"
     326That stuff is completely unreadable. Why not introduce a new operator?
     327
     328"... roughly equivalent time ..."
     329Well, C++ looks faster to me.
     330
     331"... is restricted because the resolution does not using ..."
     332Did you mean, does not use?
     333
     334"... D and go are garbage collected ..."
     335Yes, but in D, the use of the GC is optional.
     336
     337"... while respecting the talent and skill of C programmers."
     338Are you implying that other approaches are not?
     339
     340"On the surface, the project may appear as a rehash of similar mechanisms in C++."
     341Absolutely.
     342
     343"... integration with C and its programmers ..."
     344Bold claim. What makes you think you are integrated with programmers? Number of users?
     345
     346"... inline annotation at polymorphic function call sites to create a template-specialization ..."
     347This should have been mentioned sooner. Plus conflating inlining and specialization is unfortunate.
     348Does "inline" also inline the function? Or does it only specialize the code?
     349If it also inline, that's a very unfortunate design. I might want to specialize the code, but without inlining ...
     350How do I specialize a recursive function?
  • doc/proposals/references.md

    r11dbfe1 r67fa9f9  
    1717derived rvalue types such as pointer types may include qualifiers;
    1818`const int *` is a distinct type from `int *`, though the latter is safely
    19 convertable to the former.
     19convertible to the former.
    2020In general, any number of qualifiers can be safely added to the
    2121pointed-to-type of a pointer type, e.g. `int *` converts safely to
     
    2323`const volatile int *`.
    2424
    25 Since lvalues are precicely "addressable objects", in C, only lvalues can be
     25Since lvalues are precisely "addressable objects", in C, only lvalues can be
    2626used as the operand of the `&` address-of operator.
    2727Similarly, only modifiable lvalues may be used as the assigned-to
     
    147147call "lvalue of type `T`" as `T&`.
    148148There's also an obvious argument that lvalues of a (possibly-qualified) type
    149 `T` should be convertable to references of type `T`, where `T` is also
     149`T` should be convertible to references of type `T`, where `T` is also
    150150so-qualified (e.g. lvalue `int` to `int&`, lvalue `const char` to
    151151`const char&`).
    152152By similar arguments to pointer types, qualifiers should be addable to the
    153153referred-to type of a reference (e.g. `int&` to `const int&`).
    154 As a note, since pointer arithmetic is explictly not defined on `T&`,
     154As a note, since pointer arithmetic is explicitly not defined on `T&`,
    155155`restrict T&` should be allowable and would have alias-analysis rules that
    156156are actually comprehensible to mere mortals.
  • doc/user/Makefile

    r11dbfe1 r67fa9f9  
    1212
    1313FIGURES = ${addsuffix .tex, \
     14EHMHierarchy \
    1415Cdecl \
    1516pointer1 \
  • doc/user/user.tex

    r11dbfe1 r67fa9f9  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Jun 16 12:00:01 2017
    14 %% Update Count     : 2433
     13%% Last Modified On : Sun Jul  2 09:49:56 2017
     14%% Update Count     : 2503
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    2525\usepackage{textcomp}
    2626\usepackage[latin1]{inputenc}
    27 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore
    28 % removes it as a variable-name character so keyworks in variables are highlighted
    29 \DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}
    30 
    3127
    3228\usepackage{fullpage,times,comment}
     
    4844\renewcommand{\UrlFont}{\small\sf}
    4945
     46% Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore
     47% removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR
     48% AFTER HYPERREF.
     49\renewcommand{\_}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
     50\renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
     51
    5052\setlength{\topmargin}{-0.45in}                                                 % move running title into header
    5153\setlength{\headsep}{0.25in}
     
    110112\renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
    111113\pagenumbering{roman}
    112 %\linenumbers                                            % comment out to turn off line numbering
     114\linenumbers                                            % comment out to turn off line numbering
    113115
    114116\maketitle
     
    477479#endif // ! otype
    478480
    479 #include_next <bfd.h>                   §\C{// must have internal check for multiple expansion}§
     481#®include_next® <bfd.h>                 §\C{// must have internal check for multiple expansion}§
    480482
    481483#if defined( otype ) && defined( __CFA_BFD_H__ )        §\C{// reset only if set}§
     
    487489\label{f:InterpositionHeaderFile}
    488490\end{figure}
    489 
    490 
    491 \section{Declarations}
    492 \label{s:Declarations}
    493 
    494 C declaration syntax is notoriously confusing and error prone.
    495 For example, many C programmers are confused by a declaration as simple as:
    496 \begin{quote2}
    497 \begin{tabular}{@{}ll@{}}
    498 \begin{cfa}
    499 int * x[5]
    500 \end{cfa}
    501 &
    502 \raisebox{-0.75\totalheight}{\input{Cdecl}}
    503 \end{tabular}
    504 \end{quote2}
    505 Is this an array of 5 pointers to integers or a \Index{pointer} to an array of 5 integers?
    506 The fact this declaration is unclear to many C programmers means there are \Index{productivity} and \Index{safety} issues even for basic programs.
    507 Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
    508 For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
    509 \begin{cfa}
    510 int ®(*®f®())[®5®]® {...};                              §\C{definition}§
    511  ... ®(*®f®())[®3®]® += 1;                              §\C{usage}§
    512 \end{cfa}
    513 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
    514 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
    515 
    516 \CFA provides its own type, variable and routine declarations, using a different syntax.
    517 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
    518 In the following example, \R{red} is the base type and \B{blue} is qualifiers.
    519 The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type.
    520 \begin{quote2}
    521 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    522 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    523 \begin{cfa}
    524 ß[5] *ß ®int® x1;
    525 ß* [5]ß ®int® x2;
    526 ß[* [5] int]ß f®( int p )®;
    527 \end{cfa}
    528 &
    529 \begin{cfa}
    530 ®int® ß*ß x1 ß[5]ß;
    531 ®int® ß(*ßx2ß)[5]ß;
    532 ßint (*ßf®( int p )®ß)[5]ß;
    533 \end{cfa}
    534 \end{tabular}
    535 \end{quote2}
    536 The only exception is \Index{bit field} specification, which always appear to the right of the base type.
    537 % Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()© are used to indicate a routine parameter.
    538 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
    539 For instance, variables ©x© and ©y© of type \Index{pointer} to integer are defined in \CFA as follows:
    540 \begin{quote2}
    541 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    542 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    543 \begin{cfa}
    544 ®*® int x, y;
    545 \end{cfa}
    546 &
    547 \begin{cfa}
    548 int ®*®x, ®*®y;
    549 \end{cfa}
    550 \end{tabular}
    551 \end{quote2}
    552 The downside of this semantics is the need to separate regular and \Index{pointer} declarations:
    553 \begin{quote2}
    554 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    555 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    556 \begin{cfa}
    557 ®*® int x;
    558 int y;
    559 \end{cfa}
    560 &
    561 \begin{cfa}
    562 int ®*®x, y;
    563 
    564 \end{cfa}
    565 \end{tabular}
    566 \end{quote2}
    567 which is \Index{prescribing} a safety benefit.
    568 Other examples are:
    569 \begin{quote2}
    570 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
    571 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\
    572 \begin{cfa}
    573 [ 5 ] int z;
    574 [ 5 ] * char w;
    575 * [ 5 ] double v;
    576 struct s {
    577         int f0:3;
    578         * int f1;
    579         [ 5 ] * int f2;
    580 };
    581 \end{cfa}
    582 &
    583 \begin{cfa}
    584 int z[ 5 ];
    585 char * w[ 5 ];
    586 double (* v)[ 5 ];
    587 struct s {
    588         int f0:3;
    589         int * f1;
    590         int * f2[ 5 ]
    591 };
    592 \end{cfa}
    593 &
    594 \begin{cfa}
    595 // array of 5 integers
    596 // array of 5 pointers to char
    597 // pointer to array of 5 doubles
    598 
    599 // common bit field syntax
    600 
    601 
    602 
    603 \end{cfa}
    604 \end{tabular}
    605 \end{quote2}
    606 
    607 All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg:
    608 \begin{quote2}
    609 \begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}}
    610 \multicolumn{1}{c@{\hspace{1em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}} \\
    611 \begin{cfa}
    612 const * const int x;
    613 const * [ 5 ] const int y;
    614 \end{cfa}
    615 &
    616 \begin{cfa}
    617 int const * const x;
    618 const int (* const y)[ 5 ]
    619 \end{cfa}
    620 &
    621 \begin{cfa}
    622 // const pointer to const integer
    623 // const pointer to array of 5 const integers
    624 \end{cfa}
    625 \end{tabular}
    626 \end{quote2}
    627 All declaration qualifiers, \eg ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
    628 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg:
    629 \begin{quote2}
    630 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
    631 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\
    632 \begin{cfa}
    633 extern [ 5 ] int x;
    634 static * const int y;
    635 \end{cfa}
    636 &
    637 \begin{cfa}
    638 int extern x[ 5 ];
    639 const int static * y;
    640 \end{cfa}
    641 &
    642 \begin{cfa}
    643 // externally visible array of 5 integers
    644 // internally visible pointer to constant int
    645 \end{cfa}
    646 \end{tabular}
    647 \end{quote2}
    648 
    649 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©:
    650 \begin{quote2}
    651 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    652 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    653 \begin{cfa}
    654 y = (®* int®)x;
    655 i = sizeof(®[ 5 ] * int®);
    656 \end{cfa}
    657 &
    658 \begin{cfa}
    659 y = (®int *®)x;
    660 i = sizeof(®int * [ 5 ]®);
    661 \end{cfa}
    662 \end{tabular}
    663 \end{quote2}
    664 
    665 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
    666 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
    667 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems.
    668 
    669 
    670 \section{Pointer/Reference}
    671 
    672 C provides a \newterm{pointer type};
    673 \CFA adds a \newterm{reference type}.
    674 These types may be derived from an object or routine type, called the \newterm{referenced type}.
    675 Objects of these types contain an \newterm{address}, which is normally a location in memory, but may also address memory-mapped registers in hardware devices.
    676 An integer constant expression with the value 0, or such an expression cast to type ©void *©, is called a \newterm{null-pointer constant}.\footnote{
    677 One way to conceptualize the null pointer is that no variable is placed at this address, so the null-pointer address can be used to denote an uninitialized pointer/reference object;
    678 \ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.}
    679 An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment and has not been freed.
    680 Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}.
    681 
    682 A program \newterm{object} is a region of data storage in the execution environment, the contents of which can represent values.
    683 In most cases, objects are located in memory at an address, and the variable name for an object is an implicit address to the object generated by the compiler and automatically dereferenced, as in:
    684 \begin{quote2}
    685 \begin{tabular}{@{}ll@{\hspace{2em}}l@{}}
    686 \begin{cfa}
    687 int x;
    688 x = 3;
    689 int y;
    690 y = x;
    691 \end{cfa}
    692 &
    693 \raisebox{-0.45\totalheight}{\input{pointer1}}
    694 &
    695 \begin{cfa}
    696 int * ®const® x = (int *)100
    697 *x = 3;                 // implicit dereference
    698 int * ®const® y = (int *)104;
    699 *y = *x;                // implicit dereference
    700 \end{cfa}
    701 \end{tabular}
    702 \end{quote2}
    703 where the right example is how the compiler logically interprets the variables in the left example.
    704 Since a variable name only points to one address during its lifetime, it is an \Index{immutable} \Index{pointer};
    705 hence, the implicit type of pointer variables ©x© and ©y© are constant pointers in the compiler interpretation.
    706 In general, variable addresses are stored in instructions instead of loaded from memory, and hence may not occupy storage.
    707 These approaches are contrasted in the following:
    708 \begin{quote2}
    709 \begin{tabular}{@{}l|l@{}}
    710 \multicolumn{1}{c|}{explicit variable address} & \multicolumn{1}{c}{implicit variable address} \\
    711 \hline
    712 \begin{cfa}
    713 lda             r1,100                  // load address of x
    714 ld               r2,(r1)                  // load value of x
    715 lda             r3,104                  // load address of y
    716 st               r2,(r3)                  // store x into y
    717 \end{cfa}
    718 &
    719 \begin{cfa}
    720 
    721 ld              r2,(100)                // load value of x
    722 
    723 st              r2,(104)                // store x into y
    724 \end{cfa}
    725 \end{tabular}
    726 \end{quote2}
    727 Finally, the immutable nature of a variable's address and the fact that there is no storage for the variable pointer means pointer assignment\index{pointer!assignment}\index{assignment!pointer} is impossible.
    728 Therefore, the expression ©x = y© has only one meaning, ©*x = *y©, \ie manipulate values, which is why explicitly writing the dereferences is unnecessary even though it occurs implicitly as part of \Index{instruction decoding}.
    729 
    730 A \Index{pointer}/\Index{reference} object is a generalization of an object variable-name, \ie a mutable address that can point to more than one memory location during its lifetime.
    731 (Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime, and like a variable name, may not occupy storage if the literal is embedded directly into instructions.)
    732 Hence, a pointer occupies memory to store its current address, and the pointer's value is loaded by dereferencing, \eg:
    733 \begin{quote2}
    734 \begin{tabular}{@{}l@{\hspace{2em}}l@{}}
    735 \begin{cfa}
    736 int x, y, ®*® p1, ®*® p2, ®**® p3;
    737 p1 = ®&®x;               // p1 points to x
    738 p2 = p1;                 // p2 points to x
    739 p1 = ®&®y;               // p1 points to y
    740 p3 = &p2;               // p3 points to p2
    741 \end{cfa}
    742 &
    743 \raisebox{-0.5\totalheight}{\input{pointer2.pstex_t}}
    744 \end{tabular}
    745 \end{quote2}
    746 
    747 Notice, an address has a \Index{duality}\index{address!duality}: a location in memory or the value at that location.
    748 In many cases, a compiler might be able to infer the best meaning for these two cases.
    749 For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage
    750 \begin{cfa}
    751 p2 = p1 + x;                                    §\C{// compiler infers *p2 = *p1 + x;}§
    752 \end{cfa}
    753 Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
    754 Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices.
    755 
    756 Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality.
    757 In C, objects of pointer type always manipulate the pointer object's address:
    758 \begin{cfa}
    759 p1 = p2;                                                §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
    760 p2 = p1 + x;                                    §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
    761 \end{cfa}
    762 even though the assignment to ©p2© is likely incorrect, and the programmer probably meant:
    763 \begin{cfa}
    764 p1 = p2;                                                §\C{// pointer address assignment}§
    765 ®*®p2 = ®*®p1 + x;                              §\C{// pointed-to value assignment / operation}§
    766 \end{cfa}
    767 The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
    768 
    769 However, in most other situations, the pointed-to value is requested more often than the pointer address.
    770 \begin{cfa}
    771 *p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15);
    772 \end{cfa}
    773 In this case, it is tedious to explicitly write the dereferencing, and error prone when pointer arithmetic is allowed.
    774 It is better to have the compiler generate the dereferencing and have no implicit pointer arithmetic:
    775 \begin{cfa}
    776 p2 = ((p1 + p2) * (p3 - p1)) / (p3 - 15);
    777 \end{cfa}
    778 
    779 To support this common case, a reference type is introduced in \CFA, denoted by ©&©, which is the opposite dereference semantics to a pointer type, making the value at the pointed-to location the implicit semantics for dereferencing (similar but not the same as \CC \Index{reference type}s).
    780 \begin{cfa}
    781 int x, y, ®&® r1, ®&® r2, ®&&® r3;
    782 ®&®r1 = &x;                                             §\C{// r1 points to x}§
    783 ®&®r2 = &r1;                                    §\C{// r2 points to x}§
    784 ®&®r1 = &y;                                             §\C{// r1 points to y}§
    785 ®&&®r3 = ®&®&r2;                                §\C{// r3 points to r2}§
    786 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§
    787 \end{cfa}
    788 Except for auto-dereferencing by the compiler, this reference example is the same as the previous pointer example.
    789 Hence, a reference behaves like the variable name for the current variable it is pointing-to.
    790 One 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 a declaration, so the previous example becomes:
    791 \begin{cfa}
    792 ®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15);
    793 \end{cfa}
    794 When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.
    795 However, in C, the cancellation always yields a value (\Index{rvalue}).\footnote{
    796 The unary ©&© operator yields the address of its operand.
    797 If the operand has type ``type'', the result has type ``pointer to type''.
    798 If the operand is the result of a unary ©*© operator, neither that operator nor the ©&© operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.~\cite[\S~6.5.3.2--3]{C11}}
    799 For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
    800 \begin{cfa}
    801 (&®*®)r1 = &x;                                  §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
    802 \end{cfa}
    803 Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
    804 \begin{cfa}
    805 (&(&®*®)®*®)r3 = &(&®*®)r2;             §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
    806 \end{cfa}
    807 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
    808 
    809 Fundamentally, pointer and reference objects are functionally interchangeable because both contain addresses.
    810 \begin{cfa}
    811 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
    812                  &r1 = x,    &&r2 = r1,   &&&r3 = r2;
    813 ***p3 = 3;                                              §\C{// change x}§
    814 r3 = 3;                                                 §\C{// change x, ***r3}§
    815 **p3 = ...;                                             §\C{// change p1}§
    816 &r3 = ...;                                              §\C{// change r1, (\&*)**r3, 1 cancellation}§
    817 *p3 = ...;                                              §\C{// change p2}§
    818 &&r3 = ...;                                             §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
    819 &&&r3 = p3;                                             §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
    820 \end{cfa}
    821 Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types.
    822 Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of implicit dereferencing aid from the compiler.
    823 
    824 As for a pointer type, a reference type may have qualifiers:
    825 \begin{cfa}
    826 const int cx = 5;                                       §\C{// cannot change cx;}§
    827 const int & cr = cx;                            §\C{// cannot change what cr points to}§
    828 ®&®cr = &cx;                                            §\C{// can change cr}§
    829 cr = 7;                                                         §\C{// error, cannot change cx}§
    830 int & const rc = x;                                     §\C{// must be initialized}§
    831 ®&®rc = &x;                                                     §\C{// error, cannot change rc}§
    832 const int & const crc = cx;                     §\C{// must be initialized}§
    833 crc = 7;                                                        §\C{// error, cannot change cx}§
    834 ®&®crc = &cx;                                           §\C{// error, cannot change crc}§
    835 \end{cfa}
    836 Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
    837 \begin{cfa}
    838 int & const cr = *0;                            §\C{// where 0 is the int * zero}§
    839 \end{cfa}
    840 Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management:
    841 \begin{cfa}
    842 int & const cr = *malloc();
    843 cr = 5;
    844 free( &cr );
    845 cr = 7;                                                         §\C{// unsound pointer dereference}§
    846 \end{cfa}
    847 
    848 The position of the ©const© qualifier \emph{after} the pointer/reference qualifier causes confuse for C programmers.
    849 The ©const© qualifier cannot be moved before the pointer/reference qualifier for C style-declarations;
    850 \CFA-style declarations (see \VRef{s:Declarations}) attempt to address this issue:
    851 \begin{quote2}
    852 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    853 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    854 \begin{cfa}
    855 ®const® * ®const® * const int ccp;
    856 ®const® & ®const® & const int ccr;
    857 \end{cfa}
    858 &
    859 \begin{cfa}
    860 const int * ®const® * ®const® ccp;
    861 
    862 \end{cfa}
    863 \end{tabular}
    864 \end{quote2}
    865 where the \CFA declaration is read left-to-right.
    866 
    867 Finally, like pointers, references are usable and composable with other type operators and generators.
    868 \begin{cfa}
    869 int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§
    870 &ar[1] = &w;                                            §\C{// change reference array element}§
    871 typeof( ar[1] ) p;                                      §\C{// (gcc) is int, i.e., the type of referenced object}§
    872 typeof( &ar[1] ) q;                                     §\C{// (gcc) is int \&, i.e., the type of reference}§
    873 sizeof( ar[1] ) == sizeof( int );       §\C{// is true, i.e., the size of referenced object}§
    874 sizeof( &ar[1] ) == sizeof( int *)      §\C{// is true, i.e., the size of a reference}§
    875 \end{cfa}
    876 
    877 In contrast to \CFA reference types, \Index*[C++]{\CC{}}'s reference types are all ©const© references, preventing changes to the reference address, so only value assignment is possible, which eliminates half of the \Index{address duality}.
    878 Also, \CC does not allow \Index{array}s\index{array!reference} of reference\footnote{
    879 The reason for disallowing arrays of reference is unknown, but possibly comes from references being ethereal (like a textual macro), and hence, replaceable by the referant object.}
    880 \Index*{Java}'s reference types to objects (all Java objects are on the heap) are like C pointers, which always manipulate the address, and there is no (bit-wise) object assignment, so objects are explicitly cloned by shallow or deep copying, which eliminates half of the address duality.
    881 
    882 
    883 \subsection{Initialization}
    884 
    885 \Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
    886 There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
    887 Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
    888 In contrast, the left-hand side of assignment has an address that has a duality.
    889 Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
    890 \begin{cfa}
    891 int * p = &x;                                           §\C{// assign address of x}§
    892 ®int * p = x;®                                          §\C{// assign value of x}§
    893 int & r = x;                                            §\C{// must have address of x}§
    894 \end{cfa}
    895 Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
    896 Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
    897 Note, this is strictly a convenience and safety feature for a programmer.
    898 Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
    899 Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
    900 Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
    901 \begin{cfa}
    902 int & f( int & r );                                     §\C{// reference parameter and return}§
    903 z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
    904 \end{cfa}
    905 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
    906 Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
    907 \begin{cfa}
    908 int temp1 = f( x ), temp2 = f( y );
    909 z = temp1 + temp2;
    910 \end{cfa}
    911 This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
    912 otherwise references have the same syntactic  burden as pointers in these contexts.
    913 
    914 When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
    915 \begin{cfa}
    916 void f( ®const® int & cr );
    917 void g( ®const® int * cp );
    918 f( 3 );                   g( ®&®3 );
    919 f( x + y );             g( ®&®(x + y) );
    920 \end{cfa}
    921 Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
    922 The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
    923 Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
    924 
    925 \CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
    926 If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
    927 \begin{cfa}
    928 void f( int & r );
    929 void g( int * p );
    930 f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
    931 f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
    932 \end{cfa}
    933 Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
    934 This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
    935 The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
    936 
    937 %\CFA attempts to handle pointers and references in a uniform, symmetric manner.
    938 Finally, C handles \Index{routine object}s in an inconsistent way.
    939 A routine object is both a pointer and a reference (\Index{particle and wave}).
    940 \begin{cfa}
    941 void f( int i );
    942 void (*fp)( int );                                      §\C{// routine pointer}§
    943 fp = f;                                                         §\C{// reference initialization}§
    944 fp = &f;                                                        §\C{// pointer initialization}§
    945 fp = *f;                                                        §\C{// reference initialization}§
    946 fp(3);                                                          §\C{// reference invocation}§
    947 (*fp)(3);                                                       §\C{// pointer invocation}§
    948 \end{cfa}
    949 While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
    950 Instead, a routine object should be referenced by a ©const© reference:
    951 \begin{cfa}
    952 ®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
    953 fr = ...                                                        §\C{// error, cannot change code}§
    954 &fr = ...;                                                      §\C{// changing routine reference}§
    955 fr( 3 );                                                        §\C{// reference call to f}§
    956 (*fr)(3);                                                       §\C{// error, incorrect type}§
    957 \end{cfa}
    958 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
    959 Dynamic code rewriting is possible but only in special circumstances.}
    960 \CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
    961 
    962 
    963 \subsection{Address-of Semantics}
    964 
    965 In C, ©&E© is an rvalue for any expression ©E©.
    966 \CFA extends the ©&© (address-of) operator as follows:
    967 \begin{itemize}
    968 \item
    969 if ©R© is an \Index{rvalue} of type ©T &$_1$...&$_r$© where $r \ge 1$ references (©&© symbols) than ©&R© has type ©T ®*®&$_{\color{red}2}$...&$_{\color{red}r}$©, \ie ©T© pointer with $r-1$ references (©&© symbols).
    970 
    971 \item
    972 if ©L© is an \Index{lvalue} of type ©T &$_1$...&$_l$© where $l \ge 0$ references (©&© symbols) then ©&L© has type ©T ®*®&$_{\color{red}1}$...&$_{\color{red}l}$©, \ie ©T© pointer with $l$ references (©&© symbols).
    973 \end{itemize}
    974 The following example shows the first rule applied to different \Index{rvalue} contexts:
    975 \begin{cfa}
    976 int x, * px, ** ppx, *** pppx, **** ppppx;
    977 int & rx = x, && rrx = rx, &&& rrrx = rrx ;
    978 x = rrrx;               // rrrx is an lvalue with type int &&& (equivalent to x)
    979 px = &rrrx;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)
    980 ppx = &&rrrx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)
    981 pppx = &&&rrrx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)
    982 ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)
    983 \end{cfa}
    984 The following example shows the second rule applied to different \Index{lvalue} contexts:
    985 \begin{cfa}
    986 int x, * px, ** ppx, *** pppx;
    987 int & rx = x, && rrx = rx, &&& rrrx = rrx ;
    988 rrrx = 2;               // rrrx is an lvalue with type int &&& (equivalent to x)
    989 &rrrx = px;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)
    990 &&rrrx = ppx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)
    991 &&&rrrx = pppx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)
    992 \end{cfa}
    993 
    994 
    995 \subsection{Conversions}
    996 
    997 C provides a basic implicit conversion to simplify variable usage:
    998 \begin{enumerate}
    999 \setcounter{enumi}{-1}
    1000 \item
    1001 lvalue to rvalue conversion: ©cv T© converts to ©T©, which allows implicit variable dereferencing.
    1002 \begin{cfa}
    1003 int x;
    1004 x + 1;                  // lvalue variable (int) converts to rvalue for expression
    1005 \end{cfa}
    1006 An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped.
    1007 \end{enumerate}
    1008 \CFA provides three new implicit conversion for reference types to simplify reference usage.
    1009 \begin{enumerate}
    1010 \item
    1011 reference to rvalue conversion: ©cv T &© converts to ©T©, which allows implicit reference dereferencing.
    1012 \begin{cfa}
    1013 int x, &r = x, f( int p );
    1014 x = ®r® + f( ®r® );  // lvalue reference converts to rvalue
    1015 \end{cfa}
    1016 An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
    1017 
    1018 \item
    1019 lvalue to reference conversion: \lstinline[deletekeywords={lvalue}]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
    1020 \begin{cfa}
    1021 int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)
    1022 f( ®x® );               // lvalue variable (int) convert to reference (int &)
    1023 \end{cfa}
    1024 Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
    1025 Conversion can expand a type, where ©cv1© $>$ ©cv2©, \eg passing a ©const volatile int© to an ©int &©, which has high cost (\Index{warning});
    1026 furthermore, if ©cv1© has ©const© but not ©cv2©, a temporary variable is created to preserve the immutable lvalue.
    1027 
    1028 \item
    1029 rvalue to reference conversion: ©T© converts to ©cv T &©, which allows binding references to temporaries.
    1030 \begin{cfa}
    1031 int x, & f( int & p );
    1032 f( ®x + 3® );   // rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)
    1033 ®&f®(...) = &x; // rvalue result (int &) implicitly converts to lvalue temporary reference (int &)
    1034 \end{cfa}
    1035 In both case, modifications to the temporary are inaccessible (\Index{warning}).
    1036 Conversion expands the temporary-type with ©cv©, which is low cost since the temporary is inaccessible.
    1037 \end{enumerate}
    1038 
    1039 
    1040 \begin{comment}
    1041 From: Richard Bilson <rcbilson@gmail.com>
    1042 Date: Wed, 13 Jul 2016 01:58:58 +0000
    1043 Subject: Re: pointers / references
    1044 To: "Peter A. Buhr" <pabuhr@plg2.cs.uwaterloo.ca>
    1045 
    1046 As a general comment I would say that I found the section confusing, as you move back and forth
    1047 between various real and imagined programming languages. If it were me I would rewrite into two
    1048 subsections, one that specifies precisely the syntax and semantics of reference variables and
    1049 another that provides the rationale.
    1050 
    1051 I don't see any obvious problems with the syntax or semantics so far as I understand them. It's not
    1052 obvious that the description you're giving is complete, but I'm sure you'll find the special cases
    1053 as you do the implementation.
    1054 
    1055 My big gripes are mostly that you're not being as precise as you need to be in your terminology, and
    1056 that you say a few things that aren't actually true even though I generally know what you mean.
    1057 
    1058 20 C provides a pointer type; CFA adds a reference type. Both types contain an address, which is normally a
    1059 21 location in memory.
    1060 
    1061 An address is not a location in memory; an address refers to a location in memory. Furthermore it
    1062 seems weird to me to say that a type "contains" an address; rather, objects of that type do.
    1063 
    1064 21 Special addresses are used to denote certain states or access co-processor memory. By
    1065 22 convention, no variable is placed at address 0, so addresses like 0, 1, 2, 3 are often used to denote no-value
    1066 23 or other special states.
    1067 
    1068 This isn't standard C at all. There has to be one null pointer representation, but it doesn't have
    1069 to be a literal zero representation and there doesn't have to be more than one such representation.
    1070 
    1071 23 Often dereferencing a special state causes a memory fault, so checking is necessary
    1072 24 during execution.
    1073 
    1074 I don't see the connection between the two clauses here. I feel like if a bad pointer will not cause
    1075 a memory fault then I need to do more checking, not less.
    1076 
    1077 24 If the programming language assigns addresses, a program's execution is sound, \ie all
    1078 25 addresses are to valid memory locations.
    1079 
    1080 You haven't said what it means to "assign" an address, but if I use my intuitive understanding of
    1081 the term I don't see how this can be true unless you're assuming automatic storage management.
    1082 
    1083 1 Program variables are implicit pointers to memory locations generated by the compiler and automatically
    1084 2 dereferenced, as in:
    1085 
    1086 There is no reason why a variable needs to have a location in memory, and indeed in a typical
    1087 program many variables will not. In standard terminology an object identifier refers to data in the
    1088 execution environment, but not necessarily in memory.
    1089 
    1090 13 A pointer/reference is a generalization of a variable name, \ie a mutable address that can point to more
    1091 14 than one memory location during its lifetime.
    1092 
    1093 I feel like you're off the reservation here. In my world there are objects of pointer type, which
    1094 seem to be what you're describing here, but also pointer values, which can be stored in an object of
    1095 pointer type but don't necessarily have to be. For example, how would you describe the value denoted
    1096 by "&main" in a C program? I would call it a (function) pointer, but that doesn't satisfy your
    1097 definition.
    1098 
    1099 16 not occupy storage as the literal is embedded directly into instructions.) Hence, a pointer occupies memory
    1100 17 to store its current address, and the pointer's value is loaded by dereferencing, e.g.:
    1101 
    1102 As with my general objection regarding your definition of variables, there is no reason why a
    1103 pointer variable (object of pointer type) needs to occupy memory.
    1104 
    1105 21 p2 = p1 + x; // compiler infers *p2 = *p1 + x;
    1106 
    1107 What language are we in now?
    1108 
    1109 24 pointer usage. However, in C, the following cases are ambiguous, especially with pointer arithmetic:
    1110 25 p1 = p2; // p1 = p2 or *p1 = *p2
    1111 
    1112 This isn't ambiguous. it's defined to be the first option.
    1113 
    1114 26 p1 = p1 + 1; // p1 = p1 + 1 or *p1 = *p1 + 1
    1115 
    1116 Again, this statement is not ambiguous.
    1117 
    1118 13 example. Hence, a reference behaves like the variable name for the current variable it is pointing-to. The
    1119 14 simplest way to understand a reference is to imagine the compiler inserting a dereference operator before
    1120 15 the reference variable for each reference qualifier in a declaration, e.g.:
    1121 
    1122 It's hard for me to understand who the audience for this part is. I think a practical programmer is
    1123 likely to be satisfied with "a reference behaves like the variable name for the current variable it
    1124 is pointing-to," maybe with some examples. Your "simplest way" doesn't strike me as simpler than
    1125 that. It feels like you're trying to provide a more precise definition for the semantics of
    1126 references, but it isn't actually precise enough to be a formal specification. If you want to
    1127 express the semantics of references using rewrite rules that's a great way to do it, but lay the
    1128 rules out clearly, and when you're showing an example of rewriting keep your
    1129 references/pointers/values separate (right now, you use \eg "r3" to mean a reference, a pointer,
    1130 and a value).
    1131 
    1132 24 Cancellation works to arbitrary depth, and pointer and reference values are interchangeable because both
    1133 25 contain addresses.
    1134 
    1135 Except they're not interchangeable, because they have different and incompatible types.
    1136 
    1137 40 Interestingly, C++ deals with the address duality by making the pointed-to value the default, and prevent-
    1138 41 ing changes to the reference address, which eliminates half of the duality. Java deals with the address duality
    1139 42 by making address assignment the default and requiring field assignment (direct or indirect via methods),
    1140 43 \ie there is no builtin bit-wise or method-wise assignment, which eliminates half of the duality.
    1141 
    1142 I can follow this but I think that's mostly because I already understand what you're trying to
    1143 say. I don't think I've ever heard the term "method-wise assignment" and I don't see you defining
    1144 it. Furthermore Java does have value assignment of basic (non-class) types, so your summary here
    1145 feels incomplete. (If it were me I'd drop this paragraph rather than try to save it.)
    1146 
    1147 11 Hence, for type & const, there is no pointer assignment, so &rc = &x is disallowed, and the address value
    1148 12 cannot be 0 unless an arbitrary pointer is assigned to the reference.
    1149 
    1150 Given the pains you've taken to motivate every little bit of the semantics up until now, this last
    1151 clause ("the address value cannot be 0") comes out of the blue. It seems like you could have
    1152 perfectly reasonable semantics that allowed the initialization of null references.
    1153 
    1154 12 In effect, the compiler is managing the
    1155 13 addresses for type & const not the programmer, and by a programming discipline of only using references
    1156 14 with references, address errors can be prevented.
    1157 
    1158 Again, is this assuming automatic storage management?
    1159 
    1160 18 rary binding. For reference initialization (like pointer), the initializing value must be an address (lvalue) not
    1161 19 a value (rvalue).
    1162 
    1163 This sentence appears to suggest that an address and an lvalue are the same thing.
    1164 
    1165 20 int * p = &x; // both &x and x are possible interpretations
    1166 
    1167 Are you saying that we should be considering "x" as a possible interpretation of the initializer
    1168 "&x"? It seems to me that this expression has only one legitimate interpretation in context.
    1169 
    1170 21 int & r = x; // x unlikely interpretation, because of auto-dereferencing
    1171 
    1172 You mean, we can initialize a reference using an integer value? Surely we would need some sort of
    1173 cast to induce that interpretation, no?
    1174 
    1175 22 Hence, the compiler implicitly inserts a reference operator, &, before the initialization expression.
    1176 
    1177 But then the expression would have pointer type, which wouldn't be compatible with the type of r.
    1178 
    1179 22 Similarly,
    1180 23 when a reference is used for a parameter/return type, the call-site argument does not require a reference
    1181 24 operator.
    1182 
    1183 Furthermore, it would not be correct to use a reference operator.
    1184 
    1185 45 The implicit conversion allows
    1186 1 seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
    1187 2 While C' attempts to handle pointers and references in a uniform, symmetric manner, C handles routine
    1188 3 variables in an inconsistent way: a routine variable is both a pointer and a reference (particle and wave).
    1189 
    1190 After all this talk of how expressions can have both pointer and value interpretations, you're
    1191 disparaging C because it has expressions that have both pointer and value interpretations?
    1192 
    1193 On Sat, Jul 9, 2016 at 4:18 PM Peter A. Buhr <pabuhr@plg.uwaterloo.ca> wrote:
    1194 > Aaron discovered a few places where "&"s are missing and where there are too many "&", which are
    1195 > corrected in the attached updated. None of the text has changed, if you have started reading
    1196 > already.
    1197 \end{comment}
    1198 
    1199 
    1200 \section{Routine Definition}
    1201 
    1202 \CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
    1203 The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
    1204 \begin{cfa}
    1205 ®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
    1206         §\emph{routine body}§
    1207 }
    1208 \end{cfa}
    1209 where routine ©f© has three output (return values) and three input parameters.
    1210 Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications.
    1211 
    1212 In detail, the brackets, ©[]©, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
    1213 \Index*{Michael Tiemann}, with help from \Index*{Doug Lea}, provided named return values in g++, circa 1989.}
    1214 The value of each local return variable is automatically returned at routine termination.
    1215 Declaration qualifiers can only appear at the start of a routine definition, \eg:
    1216 \begin{cfa}
    1217 ®extern® [ int x ] g( int y ) {§\,§}
    1218 \end{cfa}
    1219 Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
    1220 in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
    1221 \begin{cfa}
    1222 [§\,§] g();                                                     §\C{// no input or output parameters}§
    1223 [ void ] g( void );                                     §\C{// no input or output parameters}§
    1224 \end{cfa}
    1225 
    1226 Routine f is called as follows:
    1227 \begin{cfa}
    1228 [ i, j, ch ] = f( 3, 'a', ch );
    1229 \end{cfa}
    1230 The list of return values from f and the grouping on the left-hand side of the assignment is called a \newterm{return list} and discussed in Section 12.
    1231 
    1232 \CFA style declarations cannot be used to declare parameters for K\&R style routine definitions because of the following ambiguity:
    1233 \begin{cfa}
    1234 int (*f(x))[ 5 ] int x; {}
    1235 \end{cfa}
    1236 The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter x of type array of 5 integers.
    1237 Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
    1238 As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
    1239 \begin{cfa}
    1240 typedef int foo;
    1241 int f( int (* foo) );                           §\C{// foo is redefined as a parameter name}§
    1242 \end{cfa}
    1243 The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
    1244 The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name.
    1245 The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.
    1246 
    1247 C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
    1248 \begin{cfa}
    1249 [ int ] f( * int, int * );                      §\C{// returns an integer, accepts 2 pointers to integers}§
    1250 [ * int, int * ] f( int );                      §\C{// returns 2 pointers to integers, accepts an integer}§
    1251 \end{cfa}
    1252 The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
    1253 \begin{cfa}
    1254 #define ptoa( n, d ) int (*n)[ d ]
    1255 int f( ptoa( p, 5 ) ) ...                       §\C{// expands to int f( int (*p)[ 5 ] )}§
    1256 [ int ] f( ptoa( p, 5 ) ) ...           §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
    1257 \end{cfa}
    1258 Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
    1259 
    1260 
    1261 \subsection{Named Return Values}
    1262 
    1263 \Index{Named return values} handle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in:
    1264 \begin{cfa}
    1265 int f() {
    1266         int x;
    1267         ... x = 0; ... x = y; ...
    1268         return x;
    1269 }
    1270 \end{cfa}
    1271 Because the value in the return variable is automatically returned when a \CFA routine terminates, the ©return© statement \emph{does not} contain an expression, as in:
    1272 \newline
    1273 \begin{minipage}{\linewidth}
    1274 \begin{cfa}
    1275 ®[ int x, int y ]® f() {
    1276         int z;
    1277         ... x = 0; ... y = z; ...
    1278         ®return;®                                                       §\C{// implicitly return x, y}§
    1279 }
    1280 \end{cfa}
    1281 \end{minipage}
    1282 \newline
    1283 When the return is encountered, the current values of ©x© and ©y© are returned to the calling routine.
    1284 As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in:
    1285 \begin{cfa}
    1286 [ int x, int y ] f() {
    1287         ...
    1288 }                                                                               §\C{// implicitly return x, y}§
    1289 \end{cfa}
    1290 In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
    1291 
    1292 Named return values may be used in conjunction with named parameter values;
    1293 specifically, a return and parameter can have the same name.
    1294 \begin{cfa}
    1295 [ int x, int y ] f( int, x, int y ) {
    1296         ...
    1297 }                                                                               §\C{// implicitly return x, y}§
    1298 \end{cfa}
    1299 This notation allows the compiler to eliminate temporary variables in nested routine calls.
    1300 \begin{cfa}
    1301 [ int x, int y ] f( int, x, int y );    §\C{// prototype declaration}§
    1302 int a, b;
    1303 [a, b] = f( f( f( a, b ) ) );
    1304 \end{cfa}
    1305 While the compiler normally ignores parameters names in prototype declarations, here they are used to eliminate temporary return-values by inferring that the results of each call are the inputs of the next call, and ultimately, the left-hand side of the assignment.
    1306 Hence, even without the body of routine ©f© (separate compilation), it is possible to perform a global optimization across routine calls.
    1307 The compiler warns about naming inconsistencies between routine prototype and definition in this case, and behaviour is \Index{undefined} if the programmer is inconsistent.
    1308 
    1309 
    1310 \subsection{Routine Prototype}
    1311 
    1312 The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
    1313 as well, parameter names are optional, \eg:
    1314 \begin{cfa}
    1315 [ int x ] f ();                                                 §\C{// returning int with no parameters}§
    1316 [ * int ] g (int y);                                    §\C{// returning pointer to int with int parameter}§
    1317 [ ] h ( int, char );                                    §\C{// returning no result with int and char parameters}§
    1318 [ * int, int ] j ( int );                               §\C{// returning pointer to int and int, with int parameter}§
    1319 \end{cfa}
    1320 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
    1321 It is possible to declare multiple routine-prototypes in a single declaration, but the entire type specification is distributed across \emph{all} routine names in the declaration list (see~\VRef{s:Declarations}), \eg:
    1322 \begin{quote2}
    1323 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    1324 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    1325 \begin{cfa}
    1326 [ int ] f( int ), g;
    1327 \end{cfa}
    1328 &
    1329 \begin{cfa}
    1330 int f( int ), g( int );
    1331 \end{cfa}
    1332 \end{tabular}
    1333 \end{quote2}
    1334 Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
    1335 \begin{cfa}
    1336 extern [ int ] f ( int );
    1337 static [ int ] g ( int );
    1338 \end{cfa}
    1339 
    1340 
    1341 \section{Routine Pointers}
    1342 
    1343 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    1344 \begin{cfa}
    1345 * [ int x ] () fp;                                              §\C{// pointer to routine returning int with no parameters}§
    1346 * [ * int ] (int y) gp;                                 §\C{// pointer to routine returning pointer to int with int parameter}§
    1347 * [ ] (int,char) hp;                                    §\C{// pointer to routine returning no result with int and char parameters}§
    1348 * [ * int,int ] ( int ) jp;                             §\C{// pointer to routine returning pointer to int and int, with int parameter}§
    1349 \end{cfa}
    1350 While parameter names are optional, \emph{a routine name cannot be specified};
    1351 for example, the following is incorrect:
    1352 \begin{cfa}
    1353 * [ int x ] f () fp;                                    §\C{// routine name "f" is not allowed}§
    1354 \end{cfa}
    1355 
    1356 
    1357 \section{Named and Default Arguments}
    1358 
    1359 Named\index{named arguments}\index{arguments!named} and default\index{default arguments}\index{arguments!default} arguments~\cite{Hardgrave76}\footnote{
    1360 Francez~\cite{Francez77} proposed a further extension to the named-parameter passing style, which specifies what type of communication (by value, by reference, by name) the argument is passed to the routine.}
    1361 are two mechanisms to simplify routine call.
    1362 Both mechanisms are discussed with respect to \CFA.
    1363 \begin{description}
    1364 \item[Named (or Keyword) Arguments:]
    1365 provide the ability to specify an argument to a routine call using the parameter name rather than the position of the parameter.
    1366 For example, given the routine:
    1367 \begin{cfa}
    1368 void p( int x, int y, int z ) {...}
    1369 \end{cfa}
    1370 a positional call is:
    1371 \begin{cfa}
    1372 p( 4, 7, 3 );
    1373 \end{cfa}
    1374 whereas a named (keyword) call may be:
    1375 \begin{cfa}
    1376 p( z : 3, x : 4, y : 7 );       §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
    1377 \end{cfa}
    1378 Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
    1379 The compiler rewrites a named call into a positional call.
    1380 The advantages of named parameters are:
    1381 \begin{itemize}
    1382 \item
    1383 Remembering the names of the parameters may be easier than the order in the routine definition.
    1384 \item
    1385 Parameter names provide documentation at the call site (assuming the names are descriptive).
    1386 \item
    1387 Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
    1388 \end{itemize}
    1389 
    1390 Unfortunately, named arguments do not work in C-style programming-languages because a routine prototype is not required to specify parameter names, nor do the names in the prototype have to match with the actual definition.
    1391 For example, the following routine prototypes and definition are all valid.
    1392 \begin{cfa}
    1393 void p( int, int, int );                        §\C{// equivalent prototypes}§
    1394 void p( int x, int y, int z );
    1395 void p( int y, int x, int z );
    1396 void p( int z, int y, int x );
    1397 void p( int q, int r, int s ) {}        §\C{// match with this definition}§
    1398 \end{cfa}
    1399 Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
    1400 Alternatively, prototype definitions can be eliminated by using a two-pass compilation, and implicitly creating header files for exports.
    1401 The former is easy to do, while the latter is more complex.
    1402 
    1403 Furthermore, named arguments do not work well in a \CFA-style programming-languages because they potentially introduces a new criteria for type matching.
    1404 For example, it is technically possible to disambiguate between these two overloaded definitions of ©f© based on named arguments at the call site:
    1405 \begin{cfa}
    1406 int f( int i, int j );
    1407 int f( int x, double y );
    1408 
    1409 f( j : 3, i : 4 );                              §\C{// 1st f}§
    1410 f( x : 7, y : 8.1 );                    §\C{// 2nd f}§
    1411 f( 4, 5 );                                              §\C{// ambiguous call}§
    1412 \end{cfa}
    1413 However, named arguments compound routine resolution in conjunction with conversions:
    1414 \begin{cfa}
    1415 f( i : 3, 5.7 );                                §\C{// ambiguous call ?}§
    1416 \end{cfa}
    1417 Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
    1418 Adding named argument into the routine resolution algorithm does not seem worth the complexity.
    1419 Therefore, \CFA does \emph{not} attempt to support named arguments.
    1420 
    1421 \item[Default Arguments]
    1422 provide the ability to associate a default value with a parameter so it can be optionally specified in the argument list.
    1423 For example, given the routine:
    1424 \begin{cfa}
    1425 void p( int x = 1, int y = 2, int z = 3 ) {...}
    1426 \end{cfa}
    1427 the allowable positional calls are:
    1428 \begin{cfa}
    1429 p();                                                    §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
    1430 p( 4 );                                                 §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
    1431 p( 4, 4 );                                              §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
    1432 p( 4, 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
    1433 // empty arguments
    1434 p(  , 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
    1435 p( 4,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
    1436 p( 4, 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
    1437 p( 4,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
    1438 p(  , 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
    1439 p(  ,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
    1440 p(  ,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
    1441 \end{cfa}
    1442 Here the missing arguments are inserted from the default values in the parameter list.
    1443 The compiler rewrites missing default values into explicit positional arguments.
    1444 The advantages of default values are:
    1445 \begin{itemize}
    1446 \item
    1447 Routines with a large number of parameters are often very generalized, giving a programmer a number of different options on how a computation is performed.
    1448 For many of these kinds of routines, there are standard or default settings that work for the majority of computations.
    1449 Without default values for parameters, a programmer is forced to specify these common values all the time, resulting in long argument lists that are error prone.
    1450 \item
    1451 When a routine's interface is augmented with new parameters, it extends the interface providing generalizability\footnote{
    1452 ``It should be possible for the implementor of an abstraction to increase its generality.
    1453 So long as the modified abstraction is a generalization of the original, existing uses of the abstraction will not require change.
    1454 It might be possible to modify an abstraction in a manner which is not a generalization without affecting existing uses, but, without inspecting the modules in which the uses occur, this possibility cannot be determined.
    1455 This criterion precludes the addition of parameters, unless these parameters have default or inferred values that are valid for all possible existing applications.''~\cite[p.~128]{Cormack90}}
    1456 (somewhat like the generalization provided by inheritance for classes).
    1457 That is, all existing calls are still valid, although the call must still be recompiled.
    1458 \end{itemize}
    1459 The only disadvantage of default arguments is that unintentional omission of an argument may not result in a compiler-time error.
    1460 Instead, a default value is used, which may not be the programmer's intent.
    1461 
    1462 Default values may only appear in a prototype versus definition context:
    1463 \begin{cfa}
    1464 void p( int x, int y = 2, int z = 3 );          §\C{// prototype: allowed}§
    1465 void p( int, int = 2, int = 3 );                        §\C{// prototype: allowed}§
    1466 void p( int x, int y = 2, int z = 3 ) {}        §\C{// definition: not allowed}§
    1467 \end{cfa}
    1468 The reason for this restriction is to allow separate compilation.
    1469 Multiple prototypes with different default values is an error.
    1470 \end{description}
    1471 
    1472 Ellipse (``...'') arguments present problems when used with default arguments.
    1473 The conflict occurs because both named and ellipse arguments must appear after positional arguments, giving two possibilities:
    1474 \begin{cfa}
    1475 p( /* positional */, ... , /* named */ );
    1476 p( /* positional */, /* named */, ... );
    1477 \end{cfa}
    1478 While it is possible to implement both approaches, the first possibly is more complex than the second, \eg:
    1479 \begin{cfa}
    1480 p( int x, int y, int z, ... );
    1481 p( 1, 4, 5, 6, z : 3, y : 2 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
    1482 p( 1, z : 3, y : 2, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
    1483 \end{cfa}
    1484 In the first call, it is necessary for the programmer to conceptually rewrite the call, changing named arguments into positional, before knowing where the ellipse arguments begin.
    1485 Hence, this approach seems significantly more difficult, and hence, confusing and error prone.
    1486 In the second call, the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
    1487 
    1488 The problem is exacerbated with default arguments, \eg:
    1489 \begin{cfa}
    1490 void p( int x, int y = 2, int z = 3... );
    1491 p( 1, 4, 5, 6, z : 3 );         §\C{// assume p( /* positional */, ... , /* named */ );}§
    1492 p( 1, z : 3, 4, 5, 6 );         §\C{// assume p( /* positional */, /* named */, ... );}§
    1493 \end{cfa}
    1494 The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
    1495 therefore, argument 5 subsequently conflicts with the named argument z : 3.
    1496 In the second call, the default value for y is implicitly inserted after argument 1 and the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
    1497 For these reasons, \CFA requires named arguments before ellipse arguments.
    1498 Finally, while ellipse arguments are needed for a small set of existing C routines, like printf, the extended \CFA type system largely eliminates the need for ellipse arguments (see Section 24), making much of this discussion moot.
    1499 
    1500 Default arguments and overloading (see Section 24) are complementary.
    1501 While in theory default arguments can be simulated with overloading, as in:
    1502 \begin{quote2}
    1503 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    1504 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}}   & \multicolumn{1}{c}{\textbf{overloading}}      \\
    1505 \begin{cfa}
    1506 void p( int x, int y = 2, int z = 3 ) {...}
    1507 
    1508 
    1509 \end{cfa}
    1510 &
    1511 \begin{cfa}
    1512 void p( int x, int y, int z ) {...}
    1513 void p( int x ) { p( x, 2, 3 ); }
    1514 void p( int x, int y ) { p( x, y, 3 ); }
    1515 \end{cfa}
    1516 \end{tabular}
    1517 \end{quote2}
    1518 the number of required overloaded routines is linear in the number of default values, which is unacceptable growth.
    1519 In general, overloading should only be used over default arguments if the body of the routine is significantly different.
    1520 Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
    1521 \begin{cfa}
    1522 p( 1, /* default */, 5 );               §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
    1523 \end{cfa}
    1524 
    1525 Given the \CFA restrictions above, both named and default arguments are backwards compatible.
    1526 \Index*[C++]{\CC{}} only supports default arguments;
    1527 \Index*{Ada} supports both named and default arguments.
    1528 
    1529 
    1530 \section{Unnamed Structure Fields}
    1531 
    1532 C requires each field of a structure to have a name, except for a bit field associated with a basic type, \eg:
    1533 \begin{cfa}
    1534 struct {
    1535         int f1;                                 §\C{// named field}§
    1536         int f2 : 4;                             §\C{// named field with bit field size}§
    1537         int : 3;                                §\C{// unnamed field for basic type with bit field size}§
    1538         int ;                                   §\C{// disallowed, unnamed field}§
    1539         int *;                                  §\C{// disallowed, unnamed field}§
    1540         int (*)( int );                 §\C{// disallowed, unnamed field}§
    1541 };
    1542 \end{cfa}
    1543 This requirement is relaxed by making the field name optional for all field declarations; therefore, all the field declarations in the example are allowed.
    1544 As for unnamed bit fields, an unnamed field is used for padding a structure to a particular size.
    1545 A list of unnamed fields is also supported, \eg:
    1546 \begin{cfa}
    1547 struct {
    1548         int , , ;                               §\C{// 3 unnamed fields}§
    1549 }
    1550 \end{cfa}
    1551 
    1552 
    1553 \section{Nesting}
    1554 
    1555 Nesting of types and routines is useful for controlling name visibility (\newterm{name hiding}).
    1556 
    1557 
    1558 \subsection{Type Nesting}
    1559 
    1560 \CFA allows \Index{type nesting}, and type qualification of the nested types (see \VRef[Figure]{f:TypeNestingQualification}), where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
    1561 \begin{figure}
    1562 \centering
    1563 \begin{tabular}{@{}l@{\hspace{3em}}l|l@{}}
    1564 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}}      & \multicolumn{1}{c}{\textbf{C Implicit Hoisting}}      & \multicolumn{1}{|c}{\textbf{\CFA}}    \\
    1565 \hline
    1566 \begin{cfa}
    1567 struct S {
    1568         enum C { R, G, B };
    1569         struct T {
    1570                 union U { int i, j; };
    1571                 enum C c;
    1572                 short int i, j;
    1573         };
    1574         struct T t;
    1575 } s;
    1576 
    1577 int fred() {
    1578         s.t.c = R;
    1579         struct T t = { R, 1, 2 };
    1580         enum C c;
    1581         union U u;
    1582 }
    1583 \end{cfa}
    1584 &
    1585 \begin{cfa}
    1586 enum C { R, G, B };
    1587 union U { int i, j; };
    1588 struct T {
    1589         enum C c;
    1590         short int i, j;
    1591 };
    1592 struct S {
    1593         struct T t;
    1594 } s;
    1595        
    1596 
    1597 
    1598 
    1599 
    1600 
    1601 
    1602 \end{cfa}
    1603 &
    1604 \begin{cfa}
    1605 struct S {
    1606         enum C { R, G, B };
    1607         struct T {
    1608                 union U { int i, j; };
    1609                 enum C c;
    1610                 short int i, j;
    1611         };
    1612         struct T t;
    1613 } s;
    1614 
    1615 int fred() {
    1616         s.t.c = ®S.®R;  // type qualification
    1617         struct ®S.®T t = { ®S.®R, 1, 2 };
    1618         enum ®S.®C c;
    1619         union ®S.T.®U u;
    1620 }
    1621 \end{cfa}
    1622 \end{tabular}
    1623 \caption{Type Nesting / Qualification}
    1624 \label{f:TypeNestingQualification}
    1625 \end{figure}
    1626 In the left example in C, types ©C©, ©U© and ©T© are implicitly hoisted outside of type ©S© into the containing block scope.
    1627 In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``©.©'' for type qualification, as does \Index*{Java}, rather than the \CC type-selection operator ``©::©''.
    1628 
    1629 
    1630 \subsection{Routine Nesting}
    1631 
    1632 While \CFA does not provide object programming by putting routines into structures, it does rely heavily on locally nested routines to redefine operations at or close to a call site.
    1633 For example, the C quick-sort is wrapped into the following polymorphic \CFA routine:
    1634 \begin{cfa}
    1635 forall( otype T | { int ?<?( T, T ); } )
    1636 void qsort( const T * arr, size_t dimension );
    1637 \end{cfa}
    1638 which can be used to sort in ascending and descending order by locally redefining the less-than operator into greater-than.
    1639 \begin{cfa}
    1640 const unsigned int size = 5;
    1641 int ia[size];
    1642 ...                                             §\C{// assign values to array ia}§
    1643 qsort( ia, size );              §\C{// sort ascending order using builtin ?<?}§
    1644 {
    1645         ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§
    1646         qsort( ia, size );      §\C{// sort descending order by local redefinition}§
    1647 }
    1648 \end{cfa}
    1649 
    1650 Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
    1651 the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
    1652 The following program in undefined in \CFA (and Indexc{gcc})
    1653 \begin{cfa}
    1654 [* [int]( int )] foo() {                §\C{// int (*foo())( int )}§
    1655         int ®i® = 7;
    1656         int bar( int p ) {
    1657                 ®i® += 1;                               §\C{// dependent on local variable}§
    1658                 sout | ®i® | endl;
    1659         }
    1660         return bar;                                     §\C{// undefined because of local dependence}§
    1661 }
    1662 int main() {
    1663         * [int]( int ) fp = foo();      §\C{// int (*fp)( int )}§
    1664         sout | fp( 3 ) | endl;
    1665 }
    1666 \end{cfa}
    1667 because
    1668 
    1669 Currently, there are no \Index{lambda} expressions, \ie unnamed routines because routine names are very important to properly select the correct routine.
    1670 
    1671 
    1672 \section{Tuples}
    1673 
    1674 In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call.
    1675 (More contexts are added shortly.)
    1676 A list of such elements is called a \newterm{lexical list}.
    1677 The general syntax of a lexical list is:
    1678 \begin{cfa}
    1679 [ §\emph{exprlist}§ ]
    1680 \end{cfa}
    1681 where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas.
    1682 The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator.
    1683 The following are examples of lexical lists:
    1684 \begin{cfa}
    1685 [ x, y, z ]
    1686 [ 2 ]
    1687 [ v+w, x*y, 3.14159, f() ]
    1688 \end{cfa}
    1689 Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple.
    1690 Note, a tuple is not a record (structure);
    1691 a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1).
    1692 In essence, tuples are largely a compile time phenomenon, having little or no runtime presence.
    1693 
    1694 Tuples can be organized into compile-time tuple variables;
    1695 these variables are of \newterm{tuple type}.
    1696 Tuple variables and types can be used anywhere lists of conventional variables and types can be used.
    1697 The general syntax of a tuple type is:
    1698 \begin{cfa}
    1699 [ §\emph{typelist}§ ]
    1700 \end{cfa}
    1701 where ©$\emph{typelist}$© is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.
    1702 Examples of tuple types include:
    1703 \begin{cfa}
    1704 [ unsigned int, char ]
    1705 [ double, double, double ]
    1706 [ * int, int * ]                §\C{// mix of CFA and ANSI}§
    1707 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
    1708 \end{cfa}
    1709 Like tuples, tuple types may be nested, such as ©[ [ int, int ], int ]©, which is a 2-element tuple type whose first element is itself a tuple type.
    1710 
    1711 Examples of declarations using tuple types are:
    1712 \begin{cfa}
    1713 [ int, int ] x;                 §\C{// 2 element tuple, each element of type int}§
    1714 * [ char, char ] y;             §\C{// pointer to a 2 element tuple}§
    1715 [ [ int, int ] ] z ([ int, int ]);
    1716 \end{cfa}
    1717 The last example declares an external routine that expects a 2 element tuple as an input parameter and returns a 2 element tuple as its result.
    1718 
    1719 As mentioned, tuples can appear in contexts requiring a list of value, such as an argument list of a routine call.
    1720 In unambiguous situations, the tuple brackets may be omitted, \eg a tuple that appears as an argument may have its
    1721 square brackets omitted for convenience; therefore, the following routine invocations are equivalent:
    1722 \begin{cfa}
    1723 f( [ 1, x+2, fred() ] );
    1724 f( 1, x+2, fred() );
    1725 \end{cfa}
    1726 Also, a tuple or a tuple variable may be used to supply all or part of an argument list for a routine expecting multiple input parameters or for a routine expecting a tuple as an input parameter.
    1727 For example, the following are all legal:
    1728 \begin{cfa}
    1729 [ int, int ] w1;
    1730 [ int, int, int ] w2;
    1731 [ void ] f (int, int, int); /* three input parameters of type int */
    1732 [ void ] g ([ int, int, int ]); /* 3 element tuple as input */
    1733 f( [ 1, 2, 3 ] );
    1734 f( w1, 3 );
    1735 f( 1, w1 );
    1736 f( w2 );
    1737 g( [ 1, 2, 3 ] );
    1738 g( w1, 3 );
    1739 g( 1, w1 );
    1740 g( w2 );
    1741 \end{cfa}
    1742 Note, in all cases 3 arguments are supplied even though the syntax may appear to supply less than 3. As mentioned, a
    1743 tuple does not have structure like a record; a tuple is simply converted into a list of components.
    1744 \begin{rationale}
    1745 The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; \ie a statement such as ©g( f() )© is not supported.
    1746 Using a temporary variable to store the  results of the inner routine and then passing this variable to the outer routine works, however.
    1747 \end{rationale}
    1748 
    1749 A tuple can contain a C comma expression, provided the expression containing the comma operator is enclosed in parentheses.
    1750 For instance, the following tuples are equivalent:
    1751 \begin{cfa}
    1752 [ 1, 3, 5 ]
    1753 [ 1, (2, 3), 5 ]
    1754 \end{cfa}
    1755 The second element of the second tuple is the expression (2, 3), which yields the result 3.
    1756 This requirement is the same as for comma expressions in argument lists.
    1757 
    1758 Type qualifiers, \ie const and volatile, may modify a tuple type.
    1759 The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], \ie the qualifier is distributed across all of the types in the tuple, \eg:
    1760 \begin{cfa}
    1761 const volatile [ int, float, const int ] x;
    1762 \end{cfa}
    1763 is equivalent to:
    1764 \begin{cfa}
    1765 [ const volatile int, const volatile float, const volatile int ] x;
    1766 \end{cfa}
    1767 Declaration qualifiers can only appear at the start of a \CFA tuple declaration4, \eg:
    1768 \begin{cfa}
    1769 extern [ int, int ] w1;
    1770 static [ int, int, int ] w2;
    1771 \end{cfa}
    1772 \begin{rationale}
    1773 Unfortunately, C's syntax for subscripts precluded treating them as tuples.
    1774 The C subscript list has the form ©[i][j]...© and not ©[i, j, ...]©.
    1775 Therefore, there is no syntactic way for a routine returning multiple values to specify the different subscript values, \eg ©f[g()]© always means a single subscript value because there is only one set of brackets.
    1776 Fixing this requires a major change to C because the syntactic form ©M[i, j, k]© already has a particular meaning: ©i, j, k© is a comma expression.
    1777 \end{rationale}
    1778 
    1779 
    1780 \subsection{Tuple Coercions}
    1781 
    1782 There are four coercions that can be performed on tuples and tuple variables: closing, opening, flattening and structuring.
    1783 In addition, the coercion of dereferencing can be performed on a tuple variable to yield its value(s), as for other variables.
    1784 A \newterm{closing coercion} takes a set of values and converts it into a tuple value, which is a contiguous set of values, as in:
    1785 \begin{cfa}
    1786 [ int, int, int, int ] w;
    1787 w = [ 1, 2, 3, 4 ];
    1788 \end{cfa}
    1789 First the right-hand tuple is closed into a tuple value and then the tuple value is assigned.
    1790 
    1791 An \newterm{opening coercion} is the opposite of closing; a tuple value is converted into a tuple of values, as in:
    1792 \begin{cfa}
    1793 [ a, b, c, d ] = w
    1794 \end{cfa}
    1795 ©w© is implicitly opened to yield a tuple of four values, which are then assigned individually.
    1796 
    1797 A \newterm{flattening coercion} coerces a nested tuple, \ie a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in:
    1798 \begin{cfa}
    1799 [ a, b, c, d ] = [ 1, [ 2, 3 ], 4 ];
    1800 \end{cfa}
    1801 First the right-hand tuple is flattened and then the values are assigned individually.
    1802 Flattening is also performed on tuple types.
    1803 For example, the type ©[ int, [ int, int ], int ]© can be coerced, using flattening, into the type ©[ int, int, int, int ]©.
    1804 
    1805 A \newterm{structuring coercion} is the opposite of flattening;
    1806 a tuple is structured into a more complex nested tuple.
    1807 For example, structuring the tuple ©[ 1, 2, 3, 4 ]© into the tuple ©[ 1, [ 2, 3 ], 4 ]© or the tuple type ©[ int, int, int, int ]© into the tuple type ©[ int, [ int, int ], int ]©.
    1808 In the following example, the last assignment illustrates all the tuple coercions:
    1809 \begin{cfa}
    1810 [ int, int, int, int ] w = [ 1, 2, 3, 4 ];
    1811 int x = 5;
    1812 [ x, w ] = [ w, x ];            §\C{// all four tuple coercions}§
    1813 \end{cfa}
    1814 Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
    1815 therefore, the right-hand tuple is now the tuple ©[ [ 1, 2, 3, 4 ], 5 ]©.
    1816 This tuple is then flattened, yielding ©[ 1, 2, 3, 4, 5 ]©, which is structured into ©[ 1, [ 2, 3, 4, 5 ] ]© to match the tuple type of the left-hand side.
    1817 The tuple ©[ 2, 3, 4, 5 ]© is then closed to create a tuple value.
    1818 Finally, ©x© is assigned ©1© and ©w© is assigned the tuple value using multiple assignment (see Section 14).
    1819 \begin{rationale}
    1820 A possible additional language extension is to use the structuring coercion for tuples to initialize a complex record with a tuple.
    1821 \end{rationale}
    1822 
    1823 
    1824 \section{Mass Assignment}
    1825 
    1826 \CFA permits assignment to several variables at once using mass assignment~\cite{CLU}.
    1827 Mass assignment has the following form:
    1828 \begin{cfa}
    1829 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§;
    1830 \end{cfa}
    1831 \index{lvalue}
    1832 The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement.
    1833 ©$\emph{expr}$© is any standard arithmetic expression.
    1834 Clearly, the types of the entities being assigned must be type compatible with the value of the expression.
    1835 
    1836 Mass assignment has parallel semantics, \eg the statement:
    1837 \begin{cfa}
    1838 [ x, y, z ] = 1.5;
    1839 \end{cfa}
    1840 is equivalent to:
    1841 \begin{cfa}
    1842 x = 1.5; y = 1.5; z = 1.5;
    1843 \end{cfa}
    1844 This semantics is not the same as the following in C:
    1845 \begin{cfa}
    1846 x = y = z = 1.5;
    1847 \end{cfa}
    1848 as conversions between intermediate assignments may lose information.
    1849 A more complex example is:
    1850 \begin{cfa}
    1851 [ i, y[i], z ] = a + b;
    1852 \end{cfa}
    1853 which is equivalent to:
    1854 \begin{cfa}
    1855 t = a + b;
    1856 a1 = &i; a2 = &y[i]; a3 = &z;
    1857 *a1 = t; *a2 = t; *a3 = t;
    1858 \end{cfa}
    1859 The temporary ©t© is necessary to store the value of the expression to eliminate conversion issues.
    1860 The temporaries for the addresses are needed so that locations on the left-hand side do not change as the values are assigned.
    1861 In this case, ©y[i]© uses the previous value of ©i© and not the new value set at the beginning of the mass assignment.
    1862 
    1863 
    1864 \section{Multiple Assignment}
    1865 
    1866 \CFA also supports the assignment of several values at once, known as multiple assignment~\cite{CLU,Galletly96}.
    1867 Multiple assignment has the following form:
    1868 \begin{cfa}
    1869 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ];
    1870 \end{cfa}
    1871 \index{lvalue}
    1872 The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
    1873 Each \emph{expr} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
    1874 An example of multiple assignment is:
    1875 \begin{cfa}
    1876 [ x, y, z ] = [ 1, 2, 3 ];
    1877 \end{cfa}
    1878 Here, the values ©1©, ©2© and ©3© are assigned, respectively, to the variables ©x©, ©y© and ©z©.
    1879  A more complex example is:
    1880 \begin{cfa}
    1881 [ i, y[ i ], z ] = [ 1, i, a + b ];
    1882 \end{cfa}
    1883 Here, the values ©1©, ©i© and ©a + b© are assigned to the variables ©i©, ©y[i]© and ©z©, respectively.
    1884  Note, the parallel semantics of
    1885 multiple assignment ensures:
    1886 \begin{cfa}
    1887 [ x, y ] = [ y, x ];
    1888 \end{cfa}
    1889 correctly interchanges (swaps) the values stored in ©x© and ©y©.
    1890 The following cases are errors:
    1891 \begin{cfa}
    1892 [ a, b, c ] = [ 1, 2, 3, 4 ];
    1893 [ a, b, c ] = [ 1, 2 ];
    1894 \end{cfa}
    1895 because the number of entities in the left-hand tuple is unequal with the right-hand tuple.
    1896 
    1897 As for all tuple contexts in C, side effects should not be used because C does not define an ordering for the evaluation of the elements of a tuple;
    1898 both these examples produce indeterminate results:
    1899 \begin{cfa}
    1900 f( x++, x++ );                          §\C{// C routine call with side effects in arguments}§
    1901 [ v1, v2 ] = [ x++, x++ ];      §\C{// side effects in righthand side of multiple assignment}§
    1902 \end{cfa}
    1903 
    1904 
    1905 \section{Cascade Assignment}
    1906 
    1907 As in C, \CFA mass and multiple assignments can be cascaded, producing cascade assignment.
    1908 Cascade assignment has the following form:
    1909 \begin{cfa}
    1910 §\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;
    1911 \end{cfa}
    1912 and it has the same parallel semantics as for mass and multiple assignment.
    1913 Some examples of cascade assignment are:
    1914 \begin{cfa}
    1915 x1 = y1 = x2 = y2 = 0;
    1916 [ x1, y1 ] = [ x2, y2 ] = [ x3, y3 ];
    1917 [ x1, y1 ] = [ x2, y2 ] = 0;
    1918 [ x1, y1 ] = z = 0;
    1919 \end{cfa}
    1920 As in C, the rightmost assignment is performed first, \ie assignment parses right to left.
    1921 
    1922 
    1923 \section{Field Tuples}
    1924 
    1925 Tuples may be used to select multiple fields of a record by field name.
    1926 Its general form is:
    1927 \begin{cfa}
    1928 §\emph{expr}§ . [ §\emph{fieldlist}§ ]
    1929 §\emph{expr}§ -> [ §\emph{fieldlist}§ ]
    1930 \end{cfa}
    1931 \emph{expr} is any expression yielding a value of type record, \eg ©struct©, ©union©.
    1932 Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}.
    1933 A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is
    1934 the following:
    1935 \begin{cfa}
    1936 struct s {
    1937         int f1, f2;
    1938         char f3;
    1939         double f4;
    1940 } v;
    1941 v.[ f3, f1, f2 ] = ['x', 11, 17 ];      §\C{// equivalent to v.f3 = 'x', v.f1 = 11, v.f2 = 17}§
    1942 f( v.[ f3, f1, f2 ] );                          §\C{// equivalent to f( v.f3, v.f1, v.f2 )}§
    1943 \end{cfa}
    1944 Note, the fields appearing in a record-field tuple may be specified in any order;
    1945 also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple.
    1946 
    1947 If a field of a ©struct© is itself another ©struct©, multiple fields of this subrecord can be specified using a nested record-field tuple, as in the following example:
    1948 \begin{cfa}
    1949 struct inner {
    1950         int f2, f3;
    1951 };
    1952 struct outer {
    1953         int f1;
    1954         struct inner i;
    1955         double f4;
    1956 } o;
    1957 
    1958 o.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
    1959 \end{cfa}
    1960491
    1961492
     
    2249780still works.
    2250781Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments.
    2251 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, e.g.:
     782Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg:
    2252783\begin{cfa}
    2253784®choose® ( i ) {
     
    2397928
    2398929
     930\subsection{Exception Hierarchy}
     931
     932An exception type can be derived from another exception type, just like deriving a subclass from a class, providing a kind of polymorphism among exception types.
     933The exception-type hierarchy that is created is used to organize exception types, similar to a class hierarchy in object-oriented languages, \eg:
     934\begin{center}
     935\input{EHMHierarchy}
     936\end{center}
     937A programmer can then choose to handle an exception at different degrees of specificity along the hierarchy;
     938derived exception-types support a more flexible programming style.
     939For example, higher-level code should catch general exceptions to reduce coupling to the specific implementation at the lower levels;
     940unnecessary coupling may force changes in higher-level code when low-level code changes.
     941A consequence of derived exception-types is that multiple exceptions may match, \eg:
     942\begin{cfa}
     943catch( Arithmetic )
     944\end{cfa}
     945matches all three derived exception-types: ©DivideByZero©, ©Overflow©, and ©Underflow©.
     946Because the propagation mechanisms perform a simple linear search of the handler clause for a guarded block, and selects the first matching handler, the order of catch clauses in the handler clause becomes important, \eg:
     947\begin{cfa}
     948try {
     949        ...
     950} catch( Overflow ) {   // must appear first
     951        // handle overflow
     952} catch( Arithmetic )
     953        // handle other arithmetic issues
     954}
     955\end{cfa}
     956\newterm{Multiple derivation} among exception is not supported.
     957
     958
     959\section{Declarations}
     960\label{s:Declarations}
     961
     962C declaration syntax is notoriously confusing and error prone.
     963For example, many C programmers are confused by a declaration as simple as:
     964\begin{quote2}
     965\begin{tabular}{@{}ll@{}}
     966\begin{cfa}
     967int * x[5]
     968\end{cfa}
     969&
     970\raisebox{-0.75\totalheight}{\input{Cdecl}}
     971\end{tabular}
     972\end{quote2}
     973Is this an array of 5 pointers to integers or a \Index{pointer} to an array of 5 integers?
     974The fact this declaration is unclear to many C programmers means there are \Index{productivity} and \Index{safety} issues even for basic programs.
     975Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
     976For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
     977\begin{cfa}
     978int ®(*®f®())[®5®]® {...};                              §\C{definition}§
     979 ... ®(*®f®())[®3®]® += 1;                              §\C{usage}§
     980\end{cfa}
     981Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
     982While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
     983
     984\CFA provides its own type, variable and routine declarations, using a different syntax.
     985The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
     986In the following example, \R{red} is the base type and \B{blue} is qualifiers.
     987The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type.
     988\begin{quote2}
     989\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     990\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     991\begin{cfa}
     992ß[5] *ß ®int® x1;
     993ß* [5]ß ®int® x2;
     994ß[* [5] int]ß f®( int p )®;
     995\end{cfa}
     996&
     997\begin{cfa}
     998®int® ß*ß x1 ß[5]ß;
     999®int® ß(*ßx2ß)[5]ß;
     1000ßint (*ßf®( int p )®ß)[5]ß;
     1001\end{cfa}
     1002\end{tabular}
     1003\end{quote2}
     1004The only exception is \Index{bit field} specification, which always appear to the right of the base type.
     1005% Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()© are used to indicate a routine parameter.
     1006However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
     1007For instance, variables ©x© and ©y© of type \Index{pointer} to integer are defined in \CFA as follows:
     1008\begin{quote2}
     1009\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     1010\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     1011\begin{cfa}
     1012®*® int x, y;
     1013\end{cfa}
     1014&
     1015\begin{cfa}
     1016int ®*®x, ®*®y;
     1017\end{cfa}
     1018\end{tabular}
     1019\end{quote2}
     1020The downside of this semantics is the need to separate regular and \Index{pointer} declarations:
     1021\begin{quote2}
     1022\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     1023\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     1024\begin{cfa}
     1025®*® int x;
     1026int y;
     1027\end{cfa}
     1028&
     1029\begin{cfa}
     1030int ®*®x, y;
     1031
     1032\end{cfa}
     1033\end{tabular}
     1034\end{quote2}
     1035which is \Index{prescribing} a safety benefit.
     1036Other examples are:
     1037\begin{quote2}
     1038\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
     1039\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\
     1040\begin{cfa}
     1041[ 5 ] int z;
     1042[ 5 ] * char w;
     1043* [ 5 ] double v;
     1044struct s {
     1045        int f0:3;
     1046        * int f1;
     1047        [ 5 ] * int f2;
     1048};
     1049\end{cfa}
     1050&
     1051\begin{cfa}
     1052int z[ 5 ];
     1053char * w[ 5 ];
     1054double (* v)[ 5 ];
     1055struct s {
     1056        int f0:3;
     1057        int * f1;
     1058        int * f2[ 5 ]
     1059};
     1060\end{cfa}
     1061&
     1062\begin{cfa}
     1063// array of 5 integers
     1064// array of 5 pointers to char
     1065// pointer to array of 5 doubles
     1066
     1067// common bit field syntax
     1068
     1069
     1070
     1071\end{cfa}
     1072\end{tabular}
     1073\end{quote2}
     1074
     1075All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg:
     1076\begin{quote2}
     1077\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}}
     1078\multicolumn{1}{c@{\hspace{1em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}} \\
     1079\begin{cfa}
     1080const * const int x;
     1081const * [ 5 ] const int y;
     1082\end{cfa}
     1083&
     1084\begin{cfa}
     1085int const * const x;
     1086const int (* const y)[ 5 ]
     1087\end{cfa}
     1088&
     1089\begin{cfa}
     1090// const pointer to const integer
     1091// const pointer to array of 5 const integers
     1092\end{cfa}
     1093\end{tabular}
     1094\end{quote2}
     1095All declaration qualifiers, \eg ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
     1096The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg:
     1097\begin{quote2}
     1098\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
     1099\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\
     1100\begin{cfa}
     1101extern [ 5 ] int x;
     1102static * const int y;
     1103\end{cfa}
     1104&
     1105\begin{cfa}
     1106int extern x[ 5 ];
     1107const int static * y;
     1108\end{cfa}
     1109&
     1110\begin{cfa}
     1111// externally visible array of 5 integers
     1112// internally visible pointer to constant int
     1113\end{cfa}
     1114\end{tabular}
     1115\end{quote2}
     1116
     1117The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©:
     1118\begin{quote2}
     1119\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     1120\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     1121\begin{cfa}
     1122y = (®* int®)x;
     1123i = sizeof(®[ 5 ] * int®);
     1124\end{cfa}
     1125&
     1126\begin{cfa}
     1127y = (®int *®)x;
     1128i = sizeof(®int * [ 5 ]®);
     1129\end{cfa}
     1130\end{tabular}
     1131\end{quote2}
     1132
     1133Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
     1134Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
     1135Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems.
     1136
     1137
     1138\section{Pointer/Reference}
     1139
     1140C provides a \newterm{pointer type};
     1141\CFA adds a \newterm{reference type}.
     1142These types may be derived from an object or routine type, called the \newterm{referenced type}.
     1143Objects of these types contain an \newterm{address}, which is normally a location in memory, but may also address memory-mapped registers in hardware devices.
     1144An integer constant expression with the value 0, or such an expression cast to type ©void *©, is called a \newterm{null-pointer constant}.\footnote{
     1145One way to conceptualize the null pointer is that no variable is placed at this address, so the null-pointer address can be used to denote an uninitialized pointer/reference object;
     1146\ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.}
     1147An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment and has not been freed.
     1148Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}.
     1149
     1150A program \newterm{object} is a region of data storage in the execution environment, the contents of which can represent values.
     1151In most cases, objects are located in memory at an address, and the variable name for an object is an implicit address to the object generated by the compiler and automatically dereferenced, as in:
     1152\begin{quote2}
     1153\begin{tabular}{@{}ll@{\hspace{2em}}l@{}}
     1154\begin{cfa}
     1155int x;
     1156x = 3;
     1157int y;
     1158y = x;
     1159\end{cfa}
     1160&
     1161\raisebox{-0.45\totalheight}{\input{pointer1}}
     1162&
     1163\begin{cfa}
     1164int * ®const® x = (int *)100
     1165*x = 3;                 // implicit dereference
     1166int * ®const® y = (int *)104;
     1167*y = *x;                // implicit dereference
     1168\end{cfa}
     1169\end{tabular}
     1170\end{quote2}
     1171where the right example is how the compiler logically interprets the variables in the left example.
     1172Since a variable name only points to one address during its lifetime, it is an \Index{immutable} \Index{pointer};
     1173hence, the implicit type of pointer variables ©x© and ©y© are constant pointers in the compiler interpretation.
     1174In general, variable addresses are stored in instructions instead of loaded from memory, and hence may not occupy storage.
     1175These approaches are contrasted in the following:
     1176\begin{quote2}
     1177\begin{tabular}{@{}l|l@{}}
     1178\multicolumn{1}{c|}{explicit variable address} & \multicolumn{1}{c}{implicit variable address} \\
     1179\hline
     1180\begin{cfa}
     1181lda             r1,100                  // load address of x
     1182ld               r2,(r1)                  // load value of x
     1183lda             r3,104                  // load address of y
     1184st               r2,(r3)                  // store x into y
     1185\end{cfa}
     1186&
     1187\begin{cfa}
     1188
     1189ld              r2,(100)                // load value of x
     1190
     1191st              r2,(104)                // store x into y
     1192\end{cfa}
     1193\end{tabular}
     1194\end{quote2}
     1195Finally, the immutable nature of a variable's address and the fact that there is no storage for the variable pointer means pointer assignment\index{pointer!assignment}\index{assignment!pointer} is impossible.
     1196Therefore, the expression ©x = y© has only one meaning, ©*x = *y©, \ie manipulate values, which is why explicitly writing the dereferences is unnecessary even though it occurs implicitly as part of \Index{instruction decoding}.
     1197
     1198A \Index{pointer}/\Index{reference} object is a generalization of an object variable-name, \ie a mutable address that can point to more than one memory location during its lifetime.
     1199(Similarly, an integer variable can contain multiple integer literals during its lifetime versus an integer constant representing a single literal during its lifetime, and like a variable name, may not occupy storage if the literal is embedded directly into instructions.)
     1200Hence, a pointer occupies memory to store its current address, and the pointer's value is loaded by dereferencing, \eg:
     1201\begin{quote2}
     1202\begin{tabular}{@{}l@{\hspace{2em}}l@{}}
     1203\begin{cfa}
     1204int x, y, ®*® p1, ®*® p2, ®**® p3;
     1205p1 = ®&®x;               // p1 points to x
     1206p2 = p1;                 // p2 points to x
     1207p1 = ®&®y;               // p1 points to y
     1208p3 = &p2;               // p3 points to p2
     1209\end{cfa}
     1210&
     1211\raisebox{-0.5\totalheight}{\input{pointer2.pstex_t}}
     1212\end{tabular}
     1213\end{quote2}
     1214
     1215Notice, an address has a \Index{duality}\index{address!duality}: a location in memory or the value at that location.
     1216In many cases, a compiler might be able to infer the best meaning for these two cases.
     1217For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage
     1218\begin{cfa}
     1219p2 = p1 + x;                                    §\C{// compiler infers *p2 = *p1 + x;}§
     1220\end{cfa}
     1221Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
     1222Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices.
     1223
     1224Rather than inferring dereference, most programming languages pick one implicit dereferencing semantics, and the programmer explicitly indicates the other to resolve address-duality.
     1225In C, objects of pointer type always manipulate the pointer object's address:
     1226\begin{cfa}
     1227p1 = p2;                                                §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
     1228p2 = p1 + x;                                    §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
     1229\end{cfa}
     1230even though the assignment to ©p2© is likely incorrect, and the programmer probably meant:
     1231\begin{cfa}
     1232p1 = p2;                                                §\C{// pointer address assignment}§
     1233®*®p2 = ®*®p1 + x;                              §\C{// pointed-to value assignment / operation}§
     1234\end{cfa}
     1235The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
     1236
     1237However, in most other situations, the pointed-to value is requested more often than the pointer address.
     1238\begin{cfa}
     1239*p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15);
     1240\end{cfa}
     1241In this case, it is tedious to explicitly write the dereferencing, and error prone when pointer arithmetic is allowed.
     1242It is better to have the compiler generate the dereferencing and have no implicit pointer arithmetic:
     1243\begin{cfa}
     1244p2 = ((p1 + p2) * (p3 - p1)) / (p3 - 15);
     1245\end{cfa}
     1246
     1247To support this common case, a reference type is introduced in \CFA, denoted by ©&©, which is the opposite dereference semantics to a pointer type, making the value at the pointed-to location the implicit semantics for dereferencing (similar but not the same as \CC \Index{reference type}s).
     1248\begin{cfa}
     1249int x, y, ®&® r1, ®&® r2, ®&&® r3;
     1250®&®r1 = &x;                                             §\C{// r1 points to x}§
     1251®&®r2 = &r1;                                    §\C{// r2 points to x}§
     1252®&®r1 = &y;                                             §\C{// r1 points to y}§
     1253®&&®r3 = ®&®&r2;                                §\C{// r3 points to r2}§
     1254r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§
     1255\end{cfa}
     1256Except for auto-dereferencing by the compiler, this reference example is the same as the previous pointer example.
     1257Hence, a reference behaves like the variable name for the current variable it is pointing-to.
     1258One 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 a declaration, so the previous example becomes:
     1259\begin{cfa}
     1260®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15);
     1261\end{cfa}
     1262When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.
     1263However, in C, the cancellation always yields a value (\Index{rvalue}).\footnote{
     1264The unary ©&© operator yields the address of its operand.
     1265If the operand has type ``type'', the result has type ``pointer to type''.
     1266If the operand is the result of a unary ©*© operator, neither that operator nor the ©&© operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.~\cite[\S~6.5.3.2--3]{C11}}
     1267For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
     1268\begin{cfa}
     1269(&®*®)r1 = &x;                                  §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
     1270\end{cfa}
     1271Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
     1272\begin{cfa}
     1273(&(&®*®)®*®)r3 = &(&®*®)r2;             §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
     1274\end{cfa}
     1275Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
     1276
     1277Fundamentally, pointer and reference objects are functionally interchangeable because both contain addresses.
     1278\begin{cfa}
     1279int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
     1280                 &r1 = x,    &&r2 = r1,   &&&r3 = r2;
     1281***p3 = 3;                                              §\C{// change x}§
     1282r3 = 3;                                                 §\C{// change x, ***r3}§
     1283**p3 = ...;                                             §\C{// change p1}§
     1284&r3 = ...;                                              §\C{// change r1, (\&*)**r3, 1 cancellation}§
     1285*p3 = ...;                                              §\C{// change p2}§
     1286&&r3 = ...;                                             §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
     1287&&&r3 = p3;                                             §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
     1288\end{cfa}
     1289Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types.
     1290Therefore, the choice between them is based solely on whether the address is dereferenced frequently or infrequently, which dictates the amount of implicit dereferencing aid from the compiler.
     1291
     1292As for a pointer type, a reference type may have qualifiers:
     1293\begin{cfa}
     1294const int cx = 5;                                       §\C{// cannot change cx;}§
     1295const int & cr = cx;                            §\C{// cannot change what cr points to}§
     1296®&®cr = &cx;                                            §\C{// can change cr}§
     1297cr = 7;                                                         §\C{// error, cannot change cx}§
     1298int & const rc = x;                                     §\C{// must be initialized}§
     1299®&®rc = &x;                                                     §\C{// error, cannot change rc}§
     1300const int & const crc = cx;                     §\C{// must be initialized}§
     1301crc = 7;                                                        §\C{// error, cannot change cx}§
     1302®&®crc = &cx;                                           §\C{// error, cannot change crc}§
     1303\end{cfa}
     1304Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
     1305\begin{cfa}
     1306int & const cr = *0;                            §\C{// where 0 is the int * zero}§
     1307\end{cfa}
     1308Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management:
     1309\begin{cfa}
     1310int & const cr = *malloc();
     1311cr = 5;
     1312free( &cr );
     1313cr = 7;                                                         §\C{// unsound pointer dereference}§
     1314\end{cfa}
     1315
     1316The position of the ©const© qualifier \emph{after} the pointer/reference qualifier causes confuse for C programmers.
     1317The ©const© qualifier cannot be moved before the pointer/reference qualifier for C style-declarations;
     1318\CFA-style declarations (see \VRef{s:Declarations}) attempt to address this issue:
     1319\begin{quote2}
     1320\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     1321\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     1322\begin{cfa}
     1323®const® * ®const® * const int ccp;
     1324®const® & ®const® & const int ccr;
     1325\end{cfa}
     1326&
     1327\begin{cfa}
     1328const int * ®const® * ®const® ccp;
     1329
     1330\end{cfa}
     1331\end{tabular}
     1332\end{quote2}
     1333where the \CFA declaration is read left-to-right.
     1334
     1335Finally, like pointers, references are usable and composable with other type operators and generators.
     1336\begin{cfa}
     1337int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§
     1338&ar[1] = &w;                                            §\C{// change reference array element}§
     1339typeof( ar[1] ) p;                                      §\C{// (gcc) is int, i.e., the type of referenced object}§
     1340typeof( &ar[1] ) q;                                     §\C{// (gcc) is int \&, i.e., the type of reference}§
     1341sizeof( ar[1] ) == sizeof( int );       §\C{// is true, i.e., the size of referenced object}§
     1342sizeof( &ar[1] ) == sizeof( int *)      §\C{// is true, i.e., the size of a reference}§
     1343\end{cfa}
     1344
     1345In contrast to \CFA reference types, \Index*[C++]{\CC{}}'s reference types are all ©const© references, preventing changes to the reference address, so only value assignment is possible, which eliminates half of the \Index{address duality}.
     1346Also, \CC does not allow \Index{array}s\index{array!reference} of reference\footnote{
     1347The reason for disallowing arrays of reference is unknown, but possibly comes from references being ethereal (like a textual macro), and hence, replaceable by the referant object.}
     1348\Index*{Java}'s reference types to objects (all Java objects are on the heap) are like C pointers, which always manipulate the address, and there is no (bit-wise) object assignment, so objects are explicitly cloned by shallow or deep copying, which eliminates half of the address duality.
     1349
     1350
     1351\subsection{Initialization}
     1352
     1353\Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
     1354There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
     1355Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
     1356In contrast, the left-hand side of assignment has an address that has a duality.
     1357Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
     1358\begin{cfa}
     1359int * p = &x;                                           §\C{// assign address of x}§
     1360®int * p = x;®                                          §\C{// assign value of x}§
     1361int & r = x;                                            §\C{// must have address of x}§
     1362\end{cfa}
     1363Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
     1364Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
     1365Note, this is strictly a convenience and safety feature for a programmer.
     1366Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
     1367Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
     1368Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
     1369\begin{cfa}
     1370int & f( int & r );                                     §\C{// reference parameter and return}§
     1371z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
     1372\end{cfa}
     1373Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
     1374Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
     1375\begin{cfa}
     1376int temp1 = f( x ), temp2 = f( y );
     1377z = temp1 + temp2;
     1378\end{cfa}
     1379This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
     1380otherwise references have the same syntactic  burden as pointers in these contexts.
     1381
     1382When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
     1383\begin{cfa}
     1384void f( ®const® int & cr );
     1385void g( ®const® int * cp );
     1386f( 3 );                   g( ®&®3 );
     1387f( x + y );             g( ®&®(x + y) );
     1388\end{cfa}
     1389Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
     1390The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
     1391Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
     1392
     1393\CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
     1394If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
     1395\begin{cfa}
     1396void f( int & r );
     1397void g( int * p );
     1398f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
     1399f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
     1400\end{cfa}
     1401Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
     1402This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
     1403The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
     1404
     1405%\CFA attempts to handle pointers and references in a uniform, symmetric manner.
     1406Finally, C handles \Index{routine object}s in an inconsistent way.
     1407A routine object is both a pointer and a reference (\Index{particle and wave}).
     1408\begin{cfa}
     1409void f( int i );
     1410void (*fp)( int );                                      §\C{// routine pointer}§
     1411fp = f;                                                         §\C{// reference initialization}§
     1412fp = &f;                                                        §\C{// pointer initialization}§
     1413fp = *f;                                                        §\C{// reference initialization}§
     1414fp(3);                                                          §\C{// reference invocation}§
     1415(*fp)(3);                                                       §\C{// pointer invocation}§
     1416\end{cfa}
     1417While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
     1418Instead, a routine object should be referenced by a ©const© reference:
     1419\begin{cfa}
     1420®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
     1421fr = ...                                                        §\C{// error, cannot change code}§
     1422&fr = ...;                                                      §\C{// changing routine reference}§
     1423fr( 3 );                                                        §\C{// reference call to f}§
     1424(*fr)(3);                                                       §\C{// error, incorrect type}§
     1425\end{cfa}
     1426because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
     1427Dynamic code rewriting is possible but only in special circumstances.}
     1428\CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
     1429
     1430
     1431\subsection{Address-of Semantics}
     1432
     1433In C, ©&E© is an rvalue for any expression ©E©.
     1434\CFA extends the ©&© (address-of) operator as follows:
     1435\begin{itemize}
     1436\item
     1437if ©R© is an \Index{rvalue} of type ©T &$_1$...&$_r$© where $r \ge 1$ references (©&© symbols) than ©&R© has type ©T ®*®&$_{\color{red}2}$...&$_{\color{red}r}$©, \ie ©T© pointer with $r-1$ references (©&© symbols).
     1438
     1439\item
     1440if ©L© is an \Index{lvalue} of type ©T &$_1$...&$_l$© where $l \ge 0$ references (©&© symbols) then ©&L© has type ©T ®*®&$_{\color{red}1}$...&$_{\color{red}l}$©, \ie ©T© pointer with $l$ references (©&© symbols).
     1441\end{itemize}
     1442The following example shows the first rule applied to different \Index{rvalue} contexts:
     1443\begin{cfa}
     1444int x, * px, ** ppx, *** pppx, **** ppppx;
     1445int & rx = x, && rrx = rx, &&& rrrx = rrx ;
     1446x = rrrx;               // rrrx is an lvalue with type int &&& (equivalent to x)
     1447px = &rrrx;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)
     1448ppx = &&rrrx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)
     1449pppx = &&&rrrx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)
     1450ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)
     1451\end{cfa}
     1452The following example shows the second rule applied to different \Index{lvalue} contexts:
     1453\begin{cfa}
     1454int x, * px, ** ppx, *** pppx;
     1455int & rx = x, && rrx = rx, &&& rrrx = rrx ;
     1456rrrx = 2;               // rrrx is an lvalue with type int &&& (equivalent to x)
     1457&rrrx = px;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)
     1458&&rrrx = ppx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)
     1459&&&rrrx = pppx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)
     1460\end{cfa}
     1461
     1462
     1463\subsection{Conversions}
     1464
     1465C provides a basic implicit conversion to simplify variable usage:
     1466\begin{enumerate}
     1467\setcounter{enumi}{-1}
     1468\item
     1469lvalue to rvalue conversion: ©cv T© converts to ©T©, which allows implicit variable dereferencing.
     1470\begin{cfa}
     1471int x;
     1472x + 1;                  // lvalue variable (int) converts to rvalue for expression
     1473\end{cfa}
     1474An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped.
     1475\end{enumerate}
     1476\CFA provides three new implicit conversion for reference types to simplify reference usage.
     1477\begin{enumerate}
     1478\item
     1479reference to rvalue conversion: ©cv T &© converts to ©T©, which allows implicit reference dereferencing.
     1480\begin{cfa}
     1481int x, &r = x, f( int p );
     1482x = ®r® + f( ®r® );  // lvalue reference converts to rvalue
     1483\end{cfa}
     1484An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
     1485
     1486\item
     1487lvalue to reference conversion: \lstinline[deletekeywords={lvalue}]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
     1488\begin{cfa}
     1489int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)
     1490f( ®x® );               // lvalue variable (int) convert to reference (int &)
     1491\end{cfa}
     1492Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
     1493Conversion can expand a type, where ©cv1© $>$ ©cv2©, \eg passing a ©const volatile int© to an ©int &©, which has high cost (\Index{warning});
     1494furthermore, if ©cv1© has ©const© but not ©cv2©, a temporary variable is created to preserve the immutable lvalue.
     1495
     1496\item
     1497rvalue to reference conversion: ©T© converts to ©cv T &©, which allows binding references to temporaries.
     1498\begin{cfa}
     1499int x, & f( int & p );
     1500f( ®x + 3® );   // rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)
     1501®&f®(...) = &x; // rvalue result (int &) implicitly converts to lvalue temporary reference (int &)
     1502\end{cfa}
     1503In both case, modifications to the temporary are inaccessible (\Index{warning}).
     1504Conversion expands the temporary-type with ©cv©, which is low cost since the temporary is inaccessible.
     1505\end{enumerate}
     1506
     1507
     1508\begin{comment}
     1509From: Richard Bilson <rcbilson@gmail.com>
     1510Date: Wed, 13 Jul 2016 01:58:58 +0000
     1511Subject: Re: pointers / references
     1512To: "Peter A. Buhr" <pabuhr@plg2.cs.uwaterloo.ca>
     1513
     1514As a general comment I would say that I found the section confusing, as you move back and forth
     1515between various real and imagined programming languages. If it were me I would rewrite into two
     1516subsections, one that specifies precisely the syntax and semantics of reference variables and
     1517another that provides the rationale.
     1518
     1519I don't see any obvious problems with the syntax or semantics so far as I understand them. It's not
     1520obvious that the description you're giving is complete, but I'm sure you'll find the special cases
     1521as you do the implementation.
     1522
     1523My big gripes are mostly that you're not being as precise as you need to be in your terminology, and
     1524that you say a few things that aren't actually true even though I generally know what you mean.
     1525
     152620 C provides a pointer type; CFA adds a reference type. Both types contain an address, which is normally a
     152721 location in memory.
     1528
     1529An address is not a location in memory; an address refers to a location in memory. Furthermore it
     1530seems weird to me to say that a type "contains" an address; rather, objects of that type do.
     1531
     153221 Special addresses are used to denote certain states or access co-processor memory. By
     153322 convention, no variable is placed at address 0, so addresses like 0, 1, 2, 3 are often used to denote no-value
     153423 or other special states.
     1535
     1536This isn't standard C at all. There has to be one null pointer representation, but it doesn't have
     1537to be a literal zero representation and there doesn't have to be more than one such representation.
     1538
     153923 Often dereferencing a special state causes a memory fault, so checking is necessary
     154024 during execution.
     1541
     1542I don't see the connection between the two clauses here. I feel like if a bad pointer will not cause
     1543a memory fault then I need to do more checking, not less.
     1544
     154524 If the programming language assigns addresses, a program's execution is sound, \ie all
     154625 addresses are to valid memory locations.
     1547
     1548You haven't said what it means to "assign" an address, but if I use my intuitive understanding of
     1549the term I don't see how this can be true unless you're assuming automatic storage management.
     1550
     15511 Program variables are implicit pointers to memory locations generated by the compiler and automatically
     15522 dereferenced, as in:
     1553
     1554There is no reason why a variable needs to have a location in memory, and indeed in a typical
     1555program many variables will not. In standard terminology an object identifier refers to data in the
     1556execution environment, but not necessarily in memory.
     1557
     155813 A pointer/reference is a generalization of a variable name, \ie a mutable address that can point to more
     155914 than one memory location during its lifetime.
     1560
     1561I feel like you're off the reservation here. In my world there are objects of pointer type, which
     1562seem to be what you're describing here, but also pointer values, which can be stored in an object of
     1563pointer type but don't necessarily have to be. For example, how would you describe the value denoted
     1564by "&main" in a C program? I would call it a (function) pointer, but that doesn't satisfy your
     1565definition.
     1566
     156716 not occupy storage as the literal is embedded directly into instructions.) Hence, a pointer occupies memory
     156817 to store its current address, and the pointer's value is loaded by dereferencing, \eg:
     1569
     1570As with my general objection regarding your definition of variables, there is no reason why a
     1571pointer variable (object of pointer type) needs to occupy memory.
     1572
     157321 p2 = p1 + x; // compiler infers *p2 = *p1 + x;
     1574
     1575What language are we in now?
     1576
     157724 pointer usage. However, in C, the following cases are ambiguous, especially with pointer arithmetic:
     157825 p1 = p2; // p1 = p2 or *p1 = *p2
     1579
     1580This isn't ambiguous. it's defined to be the first option.
     1581
     158226 p1 = p1 + 1; // p1 = p1 + 1 or *p1 = *p1 + 1
     1583
     1584Again, this statement is not ambiguous.
     1585
     158613 example. Hence, a reference behaves like the variable name for the current variable it is pointing-to. The
     158714 simplest way to understand a reference is to imagine the compiler inserting a dereference operator before
     158815 the reference variable for each reference qualifier in a declaration, \eg:
     1589
     1590It's hard for me to understand who the audience for this part is. I think a practical programmer is
     1591likely to be satisfied with "a reference behaves like the variable name for the current variable it
     1592is pointing-to," maybe with some examples. Your "simplest way" doesn't strike me as simpler than
     1593that. It feels like you're trying to provide a more precise definition for the semantics of
     1594references, but it isn't actually precise enough to be a formal specification. If you want to
     1595express the semantics of references using rewrite rules that's a great way to do it, but lay the
     1596rules out clearly, and when you're showing an example of rewriting keep your
     1597references/pointers/values separate (right now, you use \eg "r3" to mean a reference, a pointer,
     1598and a value).
     1599
     160024 Cancellation works to arbitrary depth, and pointer and reference values are interchangeable because both
     160125 contain addresses.
     1602
     1603Except they're not interchangeable, because they have different and incompatible types.
     1604
     160540 Interestingly, C++ deals with the address duality by making the pointed-to value the default, and prevent-
     160641 ing changes to the reference address, which eliminates half of the duality. Java deals with the address duality
     160742 by making address assignment the default and requiring field assignment (direct or indirect via methods),
     160843 \ie there is no builtin bit-wise or method-wise assignment, which eliminates half of the duality.
     1609
     1610I can follow this but I think that's mostly because I already understand what you're trying to
     1611say. I don't think I've ever heard the term "method-wise assignment" and I don't see you defining
     1612it. Furthermore Java does have value assignment of basic (non-class) types, so your summary here
     1613feels incomplete. (If it were me I'd drop this paragraph rather than try to save it.)
     1614
     161511 Hence, for type & const, there is no pointer assignment, so &rc = &x is disallowed, and the address value
     161612 cannot be 0 unless an arbitrary pointer is assigned to the reference.
     1617
     1618Given the pains you've taken to motivate every little bit of the semantics up until now, this last
     1619clause ("the address value cannot be 0") comes out of the blue. It seems like you could have
     1620perfectly reasonable semantics that allowed the initialization of null references.
     1621
     162212 In effect, the compiler is managing the
     162313 addresses for type & const not the programmer, and by a programming discipline of only using references
     162414 with references, address errors can be prevented.
     1625
     1626Again, is this assuming automatic storage management?
     1627
     162818 rary binding. For reference initialization (like pointer), the initializing value must be an address (lvalue) not
     162919 a value (rvalue).
     1630
     1631This sentence appears to suggest that an address and an lvalue are the same thing.
     1632
     163320 int * p = &x; // both &x and x are possible interpretations
     1634
     1635Are you saying that we should be considering "x" as a possible interpretation of the initializer
     1636"&x"? It seems to me that this expression has only one legitimate interpretation in context.
     1637
     163821 int & r = x; // x unlikely interpretation, because of auto-dereferencing
     1639
     1640You mean, we can initialize a reference using an integer value? Surely we would need some sort of
     1641cast to induce that interpretation, no?
     1642
     164322 Hence, the compiler implicitly inserts a reference operator, &, before the initialization expression.
     1644
     1645But then the expression would have pointer type, which wouldn't be compatible with the type of r.
     1646
     164722 Similarly,
     164823 when a reference is used for a parameter/return type, the call-site argument does not require a reference
     164924 operator.
     1650
     1651Furthermore, it would not be correct to use a reference operator.
     1652
     165345 The implicit conversion allows
     16541 seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
     16552 While C' attempts to handle pointers and references in a uniform, symmetric manner, C handles routine
     16563 variables in an inconsistent way: a routine variable is both a pointer and a reference (particle and wave).
     1657
     1658After all this talk of how expressions can have both pointer and value interpretations, you're
     1659disparaging C because it has expressions that have both pointer and value interpretations?
     1660
     1661On Sat, Jul 9, 2016 at 4:18 PM Peter A. Buhr <pabuhr@plg.uwaterloo.ca> wrote:
     1662> Aaron discovered a few places where "&"s are missing and where there are too many "&", which are
     1663> corrected in the attached updated. None of the text has changed, if you have started reading
     1664> already.
     1665\end{comment}
     1666
     1667
     1668\section{Routine Definition}
     1669
     1670\CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
     1671The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
     1672\begin{cfa}
     1673®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
     1674        §\emph{routine body}§
     1675}
     1676\end{cfa}
     1677where routine ©f© has three output (return values) and three input parameters.
     1678Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications.
     1679
     1680In detail, the brackets, ©[]©, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
     1681\Index*{Michael Tiemann}, with help from \Index*{Doug Lea}, provided named return values in g++, circa 1989.}
     1682The value of each local return variable is automatically returned at routine termination.
     1683Declaration qualifiers can only appear at the start of a routine definition, \eg:
     1684\begin{cfa}
     1685®extern® [ int x ] g( int y ) {§\,§}
     1686\end{cfa}
     1687Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
     1688in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
     1689\begin{cfa}
     1690[§\,§] g();                                                     §\C{// no input or output parameters}§
     1691[ void ] g( void );                                     §\C{// no input or output parameters}§
     1692\end{cfa}
     1693
     1694Routine f is called as follows:
     1695\begin{cfa}
     1696[ i, j, ch ] = f( 3, 'a', ch );
     1697\end{cfa}
     1698The list of return values from f and the grouping on the left-hand side of the assignment is called a \newterm{return list} and discussed in Section 12.
     1699
     1700\CFA style declarations cannot be used to declare parameters for K\&R style routine definitions because of the following ambiguity:
     1701\begin{cfa}
     1702int (*f(x))[ 5 ] int x; {}
     1703\end{cfa}
     1704The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter x of type array of 5 integers.
     1705Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
     1706As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
     1707\begin{cfa}
     1708typedef int foo;
     1709int f( int (* foo) );                           §\C{// foo is redefined as a parameter name}§
     1710\end{cfa}
     1711The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
     1712The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name.
     1713The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.
     1714
     1715C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
     1716\begin{cfa}
     1717[ int ] f( * int, int * );                      §\C{// returns an integer, accepts 2 pointers to integers}§
     1718[ * int, int * ] f( int );                      §\C{// returns 2 pointers to integers, accepts an integer}§
     1719\end{cfa}
     1720The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
     1721\begin{cfa}
     1722#define ptoa( n, d ) int (*n)[ d ]
     1723int f( ptoa( p, 5 ) ) ...                       §\C{// expands to int f( int (*p)[ 5 ] )}§
     1724[ int ] f( ptoa( p, 5 ) ) ...           §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
     1725\end{cfa}
     1726Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
     1727
     1728
     1729\subsection{Named Return Values}
     1730
     1731\Index{Named return values} handle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in:
     1732\begin{cfa}
     1733int f() {
     1734        int x;
     1735        ... x = 0; ... x = y; ...
     1736        return x;
     1737}
     1738\end{cfa}
     1739Because the value in the return variable is automatically returned when a \CFA routine terminates, the ©return© statement \emph{does not} contain an expression, as in:
     1740\newline
     1741\begin{minipage}{\linewidth}
     1742\begin{cfa}
     1743®[ int x, int y ]® f() {
     1744        int z;
     1745        ... x = 0; ... y = z; ...
     1746        ®return;®                                                       §\C{// implicitly return x, y}§
     1747}
     1748\end{cfa}
     1749\end{minipage}
     1750\newline
     1751When the return is encountered, the current values of ©x© and ©y© are returned to the calling routine.
     1752As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in:
     1753\begin{cfa}
     1754[ int x, int y ] f() {
     1755        ...
     1756}                                                                               §\C{// implicitly return x, y}§
     1757\end{cfa}
     1758In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
     1759
     1760Named return values may be used in conjunction with named parameter values;
     1761specifically, a return and parameter can have the same name.
     1762\begin{cfa}
     1763[ int x, int y ] f( int, x, int y ) {
     1764        ...
     1765}                                                                               §\C{// implicitly return x, y}§
     1766\end{cfa}
     1767This notation allows the compiler to eliminate temporary variables in nested routine calls.
     1768\begin{cfa}
     1769[ int x, int y ] f( int, x, int y );    §\C{// prototype declaration}§
     1770int a, b;
     1771[a, b] = f( f( f( a, b ) ) );
     1772\end{cfa}
     1773While the compiler normally ignores parameters names in prototype declarations, here they are used to eliminate temporary return-values by inferring that the results of each call are the inputs of the next call, and ultimately, the left-hand side of the assignment.
     1774Hence, even without the body of routine ©f© (separate compilation), it is possible to perform a global optimization across routine calls.
     1775The compiler warns about naming inconsistencies between routine prototype and definition in this case, and behaviour is \Index{undefined} if the programmer is inconsistent.
     1776
     1777
     1778\subsection{Routine Prototype}
     1779
     1780The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
     1781as well, parameter names are optional, \eg:
     1782\begin{cfa}
     1783[ int x ] f ();                                                 §\C{// returning int with no parameters}§
     1784[ * int ] g (int y);                                    §\C{// returning pointer to int with int parameter}§
     1785[ ] h ( int, char );                                    §\C{// returning no result with int and char parameters}§
     1786[ * int, int ] j ( int );                               §\C{// returning pointer to int and int, with int parameter}§
     1787\end{cfa}
     1788This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
     1789It is possible to declare multiple routine-prototypes in a single declaration, but the entire type specification is distributed across \emph{all} routine names in the declaration list (see~\VRef{s:Declarations}), \eg:
     1790\begin{quote2}
     1791\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     1792\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     1793\begin{cfa}
     1794[ int ] f( int ), g;
     1795\end{cfa}
     1796&
     1797\begin{cfa}
     1798int f( int ), g( int );
     1799\end{cfa}
     1800\end{tabular}
     1801\end{quote2}
     1802Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
     1803\begin{cfa}
     1804extern [ int ] f ( int );
     1805static [ int ] g ( int );
     1806\end{cfa}
     1807
     1808
     1809\section{Routine Pointers}
     1810
     1811The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
     1812\begin{cfa}
     1813* [ int x ] () fp;                                              §\C{// pointer to routine returning int with no parameters}§
     1814* [ * int ] (int y) gp;                                 §\C{// pointer to routine returning pointer to int with int parameter}§
     1815* [ ] (int,char) hp;                                    §\C{// pointer to routine returning no result with int and char parameters}§
     1816* [ * int,int ] ( int ) jp;                             §\C{// pointer to routine returning pointer to int and int, with int parameter}§
     1817\end{cfa}
     1818While parameter names are optional, \emph{a routine name cannot be specified};
     1819for example, the following is incorrect:
     1820\begin{cfa}
     1821* [ int x ] f () fp;                                    §\C{// routine name "f" is not allowed}§
     1822\end{cfa}
     1823
     1824
     1825\section{Named and Default Arguments}
     1826
     1827Named\index{named arguments}\index{arguments!named} and default\index{default arguments}\index{arguments!default} arguments~\cite{Hardgrave76}\footnote{
     1828Francez~\cite{Francez77} proposed a further extension to the named-parameter passing style, which specifies what type of communication (by value, by reference, by name) the argument is passed to the routine.}
     1829are two mechanisms to simplify routine call.
     1830Both mechanisms are discussed with respect to \CFA.
     1831\begin{description}
     1832\item[Named (or Keyword) Arguments:]
     1833provide the ability to specify an argument to a routine call using the parameter name rather than the position of the parameter.
     1834For example, given the routine:
     1835\begin{cfa}
     1836void p( int x, int y, int z ) {...}
     1837\end{cfa}
     1838a positional call is:
     1839\begin{cfa}
     1840p( 4, 7, 3 );
     1841\end{cfa}
     1842whereas a named (keyword) call may be:
     1843\begin{cfa}
     1844p( z : 3, x : 4, y : 7 );       §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
     1845\end{cfa}
     1846Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
     1847The compiler rewrites a named call into a positional call.
     1848The advantages of named parameters are:
     1849\begin{itemize}
     1850\item
     1851Remembering the names of the parameters may be easier than the order in the routine definition.
     1852\item
     1853Parameter names provide documentation at the call site (assuming the names are descriptive).
     1854\item
     1855Changes can be made to the order or number of parameters without affecting the call (although the call must still be recompiled).
     1856\end{itemize}
     1857
     1858Unfortunately, named arguments do not work in C-style programming-languages because a routine prototype is not required to specify parameter names, nor do the names in the prototype have to match with the actual definition.
     1859For example, the following routine prototypes and definition are all valid.
     1860\begin{cfa}
     1861void p( int, int, int );                        §\C{// equivalent prototypes}§
     1862void p( int x, int y, int z );
     1863void p( int y, int x, int z );
     1864void p( int z, int y, int x );
     1865void p( int q, int r, int s ) {}        §\C{// match with this definition}§
     1866\end{cfa}
     1867Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
     1868Alternatively, prototype definitions can be eliminated by using a two-pass compilation, and implicitly creating header files for exports.
     1869The former is easy to do, while the latter is more complex.
     1870
     1871Furthermore, named arguments do not work well in a \CFA-style programming-languages because they potentially introduces a new criteria for type matching.
     1872For example, it is technically possible to disambiguate between these two overloaded definitions of ©f© based on named arguments at the call site:
     1873\begin{cfa}
     1874int f( int i, int j );
     1875int f( int x, double y );
     1876
     1877f( j : 3, i : 4 );                              §\C{// 1st f}§
     1878f( x : 7, y : 8.1 );                    §\C{// 2nd f}§
     1879f( 4, 5 );                                              §\C{// ambiguous call}§
     1880\end{cfa}
     1881However, named arguments compound routine resolution in conjunction with conversions:
     1882\begin{cfa}
     1883f( i : 3, 5.7 );                                §\C{// ambiguous call ?}§
     1884\end{cfa}
     1885Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
     1886Adding named argument into the routine resolution algorithm does not seem worth the complexity.
     1887Therefore, \CFA does \emph{not} attempt to support named arguments.
     1888
     1889\item[Default Arguments]
     1890provide the ability to associate a default value with a parameter so it can be optionally specified in the argument list.
     1891For example, given the routine:
     1892\begin{cfa}
     1893void p( int x = 1, int y = 2, int z = 3 ) {...}
     1894\end{cfa}
     1895the allowable positional calls are:
     1896\begin{cfa}
     1897p();                                                    §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
     1898p( 4 );                                                 §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
     1899p( 4, 4 );                                              §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
     1900p( 4, 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
     1901// empty arguments
     1902p(  , 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
     1903p( 4,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
     1904p( 4, 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
     1905p( 4,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
     1906p(  , 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
     1907p(  ,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
     1908p(  ,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
     1909\end{cfa}
     1910Here the missing arguments are inserted from the default values in the parameter list.
     1911The compiler rewrites missing default values into explicit positional arguments.
     1912The advantages of default values are:
     1913\begin{itemize}
     1914\item
     1915Routines with a large number of parameters are often very generalized, giving a programmer a number of different options on how a computation is performed.
     1916For many of these kinds of routines, there are standard or default settings that work for the majority of computations.
     1917Without default values for parameters, a programmer is forced to specify these common values all the time, resulting in long argument lists that are error prone.
     1918\item
     1919When a routine's interface is augmented with new parameters, it extends the interface providing generalizability\footnote{
     1920``It should be possible for the implementor of an abstraction to increase its generality.
     1921So long as the modified abstraction is a generalization of the original, existing uses of the abstraction will not require change.
     1922It might be possible to modify an abstraction in a manner which is not a generalization without affecting existing uses, but, without inspecting the modules in which the uses occur, this possibility cannot be determined.
     1923This criterion precludes the addition of parameters, unless these parameters have default or inferred values that are valid for all possible existing applications.''~\cite[p.~128]{Cormack90}}
     1924(somewhat like the generalization provided by inheritance for classes).
     1925That is, all existing calls are still valid, although the call must still be recompiled.
     1926\end{itemize}
     1927The only disadvantage of default arguments is that unintentional omission of an argument may not result in a compiler-time error.
     1928Instead, a default value is used, which may not be the programmer's intent.
     1929
     1930Default values may only appear in a prototype versus definition context:
     1931\begin{cfa}
     1932void p( int x, int y = 2, int z = 3 );          §\C{// prototype: allowed}§
     1933void p( int, int = 2, int = 3 );                        §\C{// prototype: allowed}§
     1934void p( int x, int y = 2, int z = 3 ) {}        §\C{// definition: not allowed}§
     1935\end{cfa}
     1936The reason for this restriction is to allow separate compilation.
     1937Multiple prototypes with different default values is an error.
     1938\end{description}
     1939
     1940Ellipse (``...'') arguments present problems when used with default arguments.
     1941The conflict occurs because both named and ellipse arguments must appear after positional arguments, giving two possibilities:
     1942\begin{cfa}
     1943p( /* positional */, ... , /* named */ );
     1944p( /* positional */, /* named */, ... );
     1945\end{cfa}
     1946While it is possible to implement both approaches, the first possibly is more complex than the second, \eg:
     1947\begin{cfa}
     1948p( int x, int y, int z, ... );
     1949p( 1, 4, 5, 6, z : 3, y : 2 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
     1950p( 1, z : 3, y : 2, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
     1951\end{cfa}
     1952In the first call, it is necessary for the programmer to conceptually rewrite the call, changing named arguments into positional, before knowing where the ellipse arguments begin.
     1953Hence, this approach seems significantly more difficult, and hence, confusing and error prone.
     1954In the second call, the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
     1955
     1956The problem is exacerbated with default arguments, \eg:
     1957\begin{cfa}
     1958void p( int x, int y = 2, int z = 3... );
     1959p( 1, 4, 5, 6, z : 3 );         §\C{// assume p( /* positional */, ... , /* named */ );}§
     1960p( 1, z : 3, 4, 5, 6 );         §\C{// assume p( /* positional */, /* named */, ... );}§
     1961\end{cfa}
     1962The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
     1963therefore, argument 5 subsequently conflicts with the named argument z : 3.
     1964In the second call, the default value for y is implicitly inserted after argument 1 and the named arguments separate the positional and ellipse arguments, making it trivial to read the call.
     1965For these reasons, \CFA requires named arguments before ellipse arguments.
     1966Finally, while ellipse arguments are needed for a small set of existing C routines, like printf, the extended \CFA type system largely eliminates the need for ellipse arguments (see Section 24), making much of this discussion moot.
     1967
     1968Default arguments and overloading (see Section 24) are complementary.
     1969While in theory default arguments can be simulated with overloading, as in:
     1970\begin{quote2}
     1971\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     1972\multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}}   & \multicolumn{1}{c}{\textbf{overloading}}      \\
     1973\begin{cfa}
     1974void p( int x, int y = 2, int z = 3 ) {...}
     1975
     1976
     1977\end{cfa}
     1978&
     1979\begin{cfa}
     1980void p( int x, int y, int z ) {...}
     1981void p( int x ) { p( x, 2, 3 ); }
     1982void p( int x, int y ) { p( x, y, 3 ); }
     1983\end{cfa}
     1984\end{tabular}
     1985\end{quote2}
     1986the number of required overloaded routines is linear in the number of default values, which is unacceptable growth.
     1987In general, overloading should only be used over default arguments if the body of the routine is significantly different.
     1988Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
     1989\begin{cfa}
     1990p( 1, /* default */, 5 );               §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
     1991\end{cfa}
     1992
     1993Given the \CFA restrictions above, both named and default arguments are backwards compatible.
     1994\Index*[C++]{\CC{}} only supports default arguments;
     1995\Index*{Ada} supports both named and default arguments.
     1996
     1997
     1998\section{Unnamed Structure Fields}
     1999
     2000C requires each field of a structure to have a name, except for a bit field associated with a basic type, \eg:
     2001\begin{cfa}
     2002struct {
     2003        int f1;                                 §\C{// named field}§
     2004        int f2 : 4;                             §\C{// named field with bit field size}§
     2005        int : 3;                                §\C{// unnamed field for basic type with bit field size}§
     2006        int ;                                   §\C{// disallowed, unnamed field}§
     2007        int *;                                  §\C{// disallowed, unnamed field}§
     2008        int (*)( int );                 §\C{// disallowed, unnamed field}§
     2009};
     2010\end{cfa}
     2011This requirement is relaxed by making the field name optional for all field declarations; therefore, all the field declarations in the example are allowed.
     2012As for unnamed bit fields, an unnamed field is used for padding a structure to a particular size.
     2013A list of unnamed fields is also supported, \eg:
     2014\begin{cfa}
     2015struct {
     2016        int , , ;                               §\C{// 3 unnamed fields}§
     2017}
     2018\end{cfa}
     2019
     2020
     2021\section{Nesting}
     2022
     2023Nesting of types and routines is useful for controlling name visibility (\newterm{name hiding}).
     2024
     2025
     2026\subsection{Type Nesting}
     2027
     2028\CFA allows \Index{type nesting}, and type qualification of the nested types (see \VRef[Figure]{f:TypeNestingQualification}), where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
     2029\begin{figure}
     2030\centering
     2031\begin{tabular}{@{}l@{\hspace{3em}}l|l@{}}
     2032\multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}}      & \multicolumn{1}{c}{\textbf{C Implicit Hoisting}}      & \multicolumn{1}{|c}{\textbf{\CFA}}    \\
     2033\hline
     2034\begin{cfa}
     2035struct S {
     2036        enum C { R, G, B };
     2037        struct T {
     2038                union U { int i, j; };
     2039                enum C c;
     2040                short int i, j;
     2041        };
     2042        struct T t;
     2043} s;
     2044
     2045int fred() {
     2046        s.t.c = R;
     2047        struct T t = { R, 1, 2 };
     2048        enum C c;
     2049        union U u;
     2050}
     2051\end{cfa}
     2052&
     2053\begin{cfa}
     2054enum C { R, G, B };
     2055union U { int i, j; };
     2056struct T {
     2057        enum C c;
     2058        short int i, j;
     2059};
     2060struct S {
     2061        struct T t;
     2062} s;
     2063       
     2064
     2065
     2066
     2067
     2068
     2069
     2070\end{cfa}
     2071&
     2072\begin{cfa}
     2073struct S {
     2074        enum C { R, G, B };
     2075        struct T {
     2076                union U { int i, j; };
     2077                enum C c;
     2078                short int i, j;
     2079        };
     2080        struct T t;
     2081} s;
     2082
     2083int fred() {
     2084        s.t.c = ®S.®R;  // type qualification
     2085        struct ®S.®T t = { ®S.®R, 1, 2 };
     2086        enum ®S.®C c;
     2087        union ®S.T.®U u;
     2088}
     2089\end{cfa}
     2090\end{tabular}
     2091\caption{Type Nesting / Qualification}
     2092\label{f:TypeNestingQualification}
     2093\end{figure}
     2094In the left example in C, types ©C©, ©U© and ©T© are implicitly hoisted outside of type ©S© into the containing block scope.
     2095In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``©.©'' for type qualification, as does \Index*{Java}, rather than the \CC type-selection operator ``©::©''.
     2096
     2097
     2098\subsection{Routine Nesting}
     2099
     2100While \CFA does not provide object programming by putting routines into structures, it does rely heavily on locally nested routines to redefine operations at or close to a call site.
     2101For example, the C quick-sort is wrapped into the following polymorphic \CFA routine:
     2102\begin{cfa}
     2103forall( otype T | { int ?<?( T, T ); } )
     2104void qsort( const T * arr, size_t dimension );
     2105\end{cfa}
     2106which can be used to sort in ascending and descending order by locally redefining the less-than operator into greater-than.
     2107\begin{cfa}
     2108const unsigned int size = 5;
     2109int ia[size];
     2110...                                             §\C{// assign values to array ia}§
     2111qsort( ia, size );              §\C{// sort ascending order using builtin ?<?}§
     2112{
     2113        ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§
     2114        qsort( ia, size );      §\C{// sort descending order by local redefinition}§
     2115}
     2116\end{cfa}
     2117
     2118Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
     2119the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
     2120The following program in undefined in \CFA (and Indexc{gcc})
     2121\begin{cfa}
     2122[* [int]( int )] foo() {                §\C{// int (*foo())( int )}§
     2123        int ®i® = 7;
     2124        int bar( int p ) {
     2125                ®i® += 1;                               §\C{// dependent on local variable}§
     2126                sout | ®i® | endl;
     2127        }
     2128        return bar;                                     §\C{// undefined because of local dependence}§
     2129}
     2130int main() {
     2131        * [int]( int ) fp = foo();      §\C{// int (*fp)( int )}§
     2132        sout | fp( 3 ) | endl;
     2133}
     2134\end{cfa}
     2135because
     2136
     2137Currently, there are no \Index{lambda} expressions, \ie unnamed routines because routine names are very important to properly select the correct routine.
     2138
     2139
     2140\section{Tuples}
     2141
     2142In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call.
     2143(More contexts are added shortly.)
     2144A list of such elements is called a \newterm{lexical list}.
     2145The general syntax of a lexical list is:
     2146\begin{cfa}
     2147[ §\emph{exprlist}§ ]
     2148\end{cfa}
     2149where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas.
     2150The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator.
     2151The following are examples of lexical lists:
     2152\begin{cfa}
     2153[ x, y, z ]
     2154[ 2 ]
     2155[ v+w, x*y, 3.14159, f() ]
     2156\end{cfa}
     2157Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple.
     2158Note, a tuple is not a record (structure);
     2159a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1).
     2160In essence, tuples are largely a compile time phenomenon, having little or no runtime presence.
     2161
     2162Tuples can be organized into compile-time tuple variables;
     2163these variables are of \newterm{tuple type}.
     2164Tuple variables and types can be used anywhere lists of conventional variables and types can be used.
     2165The general syntax of a tuple type is:
     2166\begin{cfa}
     2167[ §\emph{typelist}§ ]
     2168\end{cfa}
     2169where ©$\emph{typelist}$© is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.
     2170Examples of tuple types include:
     2171\begin{cfa}
     2172[ unsigned int, char ]
     2173[ double, double, double ]
     2174[ * int, int * ]                §\C{// mix of CFA and ANSI}§
     2175[ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
     2176\end{cfa}
     2177Like tuples, tuple types may be nested, such as ©[ [ int, int ], int ]©, which is a 2-element tuple type whose first element is itself a tuple type.
     2178
     2179Examples of declarations using tuple types are:
     2180\begin{cfa}
     2181[ int, int ] x;                 §\C{// 2 element tuple, each element of type int}§
     2182* [ char, char ] y;             §\C{// pointer to a 2 element tuple}§
     2183[ [ int, int ] ] z ([ int, int ]);
     2184\end{cfa}
     2185The last example declares an external routine that expects a 2 element tuple as an input parameter and returns a 2 element tuple as its result.
     2186
     2187As mentioned, tuples can appear in contexts requiring a list of value, such as an argument list of a routine call.
     2188In unambiguous situations, the tuple brackets may be omitted, \eg a tuple that appears as an argument may have its
     2189square brackets omitted for convenience; therefore, the following routine invocations are equivalent:
     2190\begin{cfa}
     2191f( [ 1, x+2, fred() ] );
     2192f( 1, x+2, fred() );
     2193\end{cfa}
     2194Also, a tuple or a tuple variable may be used to supply all or part of an argument list for a routine expecting multiple input parameters or for a routine expecting a tuple as an input parameter.
     2195For example, the following are all legal:
     2196\begin{cfa}
     2197[ int, int ] w1;
     2198[ int, int, int ] w2;
     2199[ void ] f (int, int, int); /* three input parameters of type int */
     2200[ void ] g ([ int, int, int ]); /* 3 element tuple as input */
     2201f( [ 1, 2, 3 ] );
     2202f( w1, 3 );
     2203f( 1, w1 );
     2204f( w2 );
     2205g( [ 1, 2, 3 ] );
     2206g( w1, 3 );
     2207g( 1, w1 );
     2208g( w2 );
     2209\end{cfa}
     2210Note, in all cases 3 arguments are supplied even though the syntax may appear to supply less than 3. As mentioned, a
     2211tuple does not have structure like a record; a tuple is simply converted into a list of components.
     2212\begin{rationale}
     2213The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; \ie a statement such as ©g( f() )© is not supported.
     2214Using a temporary variable to store the  results of the inner routine and then passing this variable to the outer routine works, however.
     2215\end{rationale}
     2216
     2217A tuple can contain a C comma expression, provided the expression containing the comma operator is enclosed in parentheses.
     2218For instance, the following tuples are equivalent:
     2219\begin{cfa}
     2220[ 1, 3, 5 ]
     2221[ 1, (2, 3), 5 ]
     2222\end{cfa}
     2223The second element of the second tuple is the expression (2, 3), which yields the result 3.
     2224This requirement is the same as for comma expressions in argument lists.
     2225
     2226Type qualifiers, \ie const and volatile, may modify a tuple type.
     2227The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], \ie the qualifier is distributed across all of the types in the tuple, \eg:
     2228\begin{cfa}
     2229const volatile [ int, float, const int ] x;
     2230\end{cfa}
     2231is equivalent to:
     2232\begin{cfa}
     2233[ const volatile int, const volatile float, const volatile int ] x;
     2234\end{cfa}
     2235Declaration qualifiers can only appear at the start of a \CFA tuple declaration4, \eg:
     2236\begin{cfa}
     2237extern [ int, int ] w1;
     2238static [ int, int, int ] w2;
     2239\end{cfa}
     2240\begin{rationale}
     2241Unfortunately, C's syntax for subscripts precluded treating them as tuples.
     2242The C subscript list has the form ©[i][j]...© and not ©[i, j, ...]©.
     2243Therefore, there is no syntactic way for a routine returning multiple values to specify the different subscript values, \eg ©f[g()]© always means a single subscript value because there is only one set of brackets.
     2244Fixing this requires a major change to C because the syntactic form ©M[i, j, k]© already has a particular meaning: ©i, j, k© is a comma expression.
     2245\end{rationale}
     2246
     2247
     2248\subsection{Tuple Coercions}
     2249
     2250There are four coercions that can be performed on tuples and tuple variables: closing, opening, flattening and structuring.
     2251In addition, the coercion of dereferencing can be performed on a tuple variable to yield its value(s), as for other variables.
     2252A \newterm{closing coercion} takes a set of values and converts it into a tuple value, which is a contiguous set of values, as in:
     2253\begin{cfa}
     2254[ int, int, int, int ] w;
     2255w = [ 1, 2, 3, 4 ];
     2256\end{cfa}
     2257First the right-hand tuple is closed into a tuple value and then the tuple value is assigned.
     2258
     2259An \newterm{opening coercion} is the opposite of closing; a tuple value is converted into a tuple of values, as in:
     2260\begin{cfa}
     2261[ a, b, c, d ] = w
     2262\end{cfa}
     2263©w© is implicitly opened to yield a tuple of four values, which are then assigned individually.
     2264
     2265A \newterm{flattening coercion} coerces a nested tuple, \ie a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in:
     2266\begin{cfa}
     2267[ a, b, c, d ] = [ 1, [ 2, 3 ], 4 ];
     2268\end{cfa}
     2269First the right-hand tuple is flattened and then the values are assigned individually.
     2270Flattening is also performed on tuple types.
     2271For example, the type ©[ int, [ int, int ], int ]© can be coerced, using flattening, into the type ©[ int, int, int, int ]©.
     2272
     2273A \newterm{structuring coercion} is the opposite of flattening;
     2274a tuple is structured into a more complex nested tuple.
     2275For example, structuring the tuple ©[ 1, 2, 3, 4 ]© into the tuple ©[ 1, [ 2, 3 ], 4 ]© or the tuple type ©[ int, int, int, int ]© into the tuple type ©[ int, [ int, int ], int ]©.
     2276In the following example, the last assignment illustrates all the tuple coercions:
     2277\begin{cfa}
     2278[ int, int, int, int ] w = [ 1, 2, 3, 4 ];
     2279int x = 5;
     2280[ x, w ] = [ w, x ];            §\C{// all four tuple coercions}§
     2281\end{cfa}
     2282Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
     2283therefore, the right-hand tuple is now the tuple ©[ [ 1, 2, 3, 4 ], 5 ]©.
     2284This tuple is then flattened, yielding ©[ 1, 2, 3, 4, 5 ]©, which is structured into ©[ 1, [ 2, 3, 4, 5 ] ]© to match the tuple type of the left-hand side.
     2285The tuple ©[ 2, 3, 4, 5 ]© is then closed to create a tuple value.
     2286Finally, ©x© is assigned ©1© and ©w© is assigned the tuple value using multiple assignment (see Section 14).
     2287\begin{rationale}
     2288A possible additional language extension is to use the structuring coercion for tuples to initialize a complex record with a tuple.
     2289\end{rationale}
     2290
     2291
     2292\section{Mass Assignment}
     2293
     2294\CFA permits assignment to several variables at once using mass assignment~\cite{CLU}.
     2295Mass assignment has the following form:
     2296\begin{cfa}
     2297[ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§;
     2298\end{cfa}
     2299\index{lvalue}
     2300The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement.
     2301©$\emph{expr}$© is any standard arithmetic expression.
     2302Clearly, the types of the entities being assigned must be type compatible with the value of the expression.
     2303
     2304Mass assignment has parallel semantics, \eg the statement:
     2305\begin{cfa}
     2306[ x, y, z ] = 1.5;
     2307\end{cfa}
     2308is equivalent to:
     2309\begin{cfa}
     2310x = 1.5; y = 1.5; z = 1.5;
     2311\end{cfa}
     2312This semantics is not the same as the following in C:
     2313\begin{cfa}
     2314x = y = z = 1.5;
     2315\end{cfa}
     2316as conversions between intermediate assignments may lose information.
     2317A more complex example is:
     2318\begin{cfa}
     2319[ i, y[i], z ] = a + b;
     2320\end{cfa}
     2321which is equivalent to:
     2322\begin{cfa}
     2323t = a + b;
     2324a1 = &i; a2 = &y[i]; a3 = &z;
     2325*a1 = t; *a2 = t; *a3 = t;
     2326\end{cfa}
     2327The temporary ©t© is necessary to store the value of the expression to eliminate conversion issues.
     2328The temporaries for the addresses are needed so that locations on the left-hand side do not change as the values are assigned.
     2329In this case, ©y[i]© uses the previous value of ©i© and not the new value set at the beginning of the mass assignment.
     2330
     2331
     2332\section{Multiple Assignment}
     2333
     2334\CFA also supports the assignment of several values at once, known as multiple assignment~\cite{CLU,Galletly96}.
     2335Multiple assignment has the following form:
     2336\begin{cfa}
     2337[ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ];
     2338\end{cfa}
     2339\index{lvalue}
     2340The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
     2341Each \emph{expr} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
     2342An example of multiple assignment is:
     2343\begin{cfa}
     2344[ x, y, z ] = [ 1, 2, 3 ];
     2345\end{cfa}
     2346Here, the values ©1©, ©2© and ©3© are assigned, respectively, to the variables ©x©, ©y© and ©z©.
     2347 A more complex example is:
     2348\begin{cfa}
     2349[ i, y[ i ], z ] = [ 1, i, a + b ];
     2350\end{cfa}
     2351Here, the values ©1©, ©i© and ©a + b© are assigned to the variables ©i©, ©y[i]© and ©z©, respectively.
     2352 Note, the parallel semantics of
     2353multiple assignment ensures:
     2354\begin{cfa}
     2355[ x, y ] = [ y, x ];
     2356\end{cfa}
     2357correctly interchanges (swaps) the values stored in ©x© and ©y©.
     2358The following cases are errors:
     2359\begin{cfa}
     2360[ a, b, c ] = [ 1, 2, 3, 4 ];
     2361[ a, b, c ] = [ 1, 2 ];
     2362\end{cfa}
     2363because the number of entities in the left-hand tuple is unequal with the right-hand tuple.
     2364
     2365As for all tuple contexts in C, side effects should not be used because C does not define an ordering for the evaluation of the elements of a tuple;
     2366both these examples produce indeterminate results:
     2367\begin{cfa}
     2368f( x++, x++ );                          §\C{// C routine call with side effects in arguments}§
     2369[ v1, v2 ] = [ x++, x++ ];      §\C{// side effects in righthand side of multiple assignment}§
     2370\end{cfa}
     2371
     2372
     2373\section{Cascade Assignment}
     2374
     2375As in C, \CFA mass and multiple assignments can be cascaded, producing cascade assignment.
     2376Cascade assignment has the following form:
     2377\begin{cfa}
     2378§\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;
     2379\end{cfa}
     2380and it has the same parallel semantics as for mass and multiple assignment.
     2381Some examples of cascade assignment are:
     2382\begin{cfa}
     2383x1 = y1 = x2 = y2 = 0;
     2384[ x1, y1 ] = [ x2, y2 ] = [ x3, y3 ];
     2385[ x1, y1 ] = [ x2, y2 ] = 0;
     2386[ x1, y1 ] = z = 0;
     2387\end{cfa}
     2388As in C, the rightmost assignment is performed first, \ie assignment parses right to left.
     2389
     2390
     2391\section{Field Tuples}
     2392
     2393Tuples may be used to select multiple fields of a record by field name.
     2394Its general form is:
     2395\begin{cfa}
     2396§\emph{expr}§ . [ §\emph{fieldlist}§ ]
     2397§\emph{expr}§ -> [ §\emph{fieldlist}§ ]
     2398\end{cfa}
     2399\emph{expr} is any expression yielding a value of type record, \eg ©struct©, ©union©.
     2400Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}.
     2401A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is
     2402the following:
     2403\begin{cfa}
     2404struct s {
     2405        int f1, f2;
     2406        char f3;
     2407        double f4;
     2408} v;
     2409v.[ f3, f1, f2 ] = ['x', 11, 17 ];      §\C{// equivalent to v.f3 = 'x', v.f1 = 11, v.f2 = 17}§
     2410f( v.[ f3, f1, f2 ] );                          §\C{// equivalent to f( v.f3, v.f1, v.f2 )}§
     2411\end{cfa}
     2412Note, the fields appearing in a record-field tuple may be specified in any order;
     2413also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple.
     2414
     2415If a field of a ©struct© is itself another ©struct©, multiple fields of this subrecord can be specified using a nested record-field tuple, as in the following example:
     2416\begin{cfa}
     2417struct inner {
     2418        int f2, f3;
     2419};
     2420struct outer {
     2421        int f1;
     2422        struct inner i;
     2423        double f4;
     2424} o;
     2425
     2426o.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
     2427\end{cfa}
     2428
     2429
    23992430\section{I/O Library}
    24002431\label{s:IOLibrary}
     
    24022433
    24032434The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
     2435The approach combines ideas from \CC and Python.
    24042436The \CFA header file for the I/O library is \Indexc{fstream}.
    24052437
     
    24192451\\
    24202452\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    2421 1 2 3
     24531® ®2® ®3
    24222454\end{cfa}
    24232455&
     
    24272459\end{tabular}
    24282460\end{quote2}
    2429 The \CFA form has half as many characters as the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
    2430 A tuple prints all the tuple's values, each separated by ©", "©.
     2461The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
     2462Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''.
    24312463\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2432 [int, int] t1 = [1, 2], t2 = [3, 4];
     2464[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
    24332465sout | t1 | t2 | endl;                                  §\C{// print tuples}§
    24342466\end{cfa}
    24352467\begin{cfa}[mathescape=off,showspaces=true,belowskip=0pt]
    2436 1, 2, 3, 4
    2437 \end{cfa}
    2438 \CFA uses the logical-or operator for I/O because it is the lowest-priority overloadable operator, other than assignment.
     24681®, ®2®, ®3 3®, ®4®, ®5
     2469\end{cfa}
     2470Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment.
    24392471Therefore, fewer output expressions require parenthesis.
    24402472\begin{quote2}
     
    24582490\end{tabular}
    24592491\end{quote2}
    2460 Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
    2461 
    2462 
    2463 The implicit separator\index{I/O!separator} character (space/blank) is a separator not a terminator.
     2492There is a weak similarity between the \CFA logical-or operator and the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
     2493
     2494
     2495\subsection{Implicit Separator}
     2496
     2497The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator.
    24642498The rules for implicitly adding the separator are:
    24652499\begin{enumerate}
     
    25332567\end{enumerate}
    25342568
     2569
     2570\subsection{Manipulator}
     2571
    25352572The following routines and \CC-style \Index{manipulator}s control implicit seperation.
    25362573\begin{enumerate}
     
    25442581%$
    25452582\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    2546 1, $2, $3 ®", $"®
     25831®, $®2®, $®3 ®", $"®
    25472584\end{cfa}
    25482585%$
     
    25522589\end{cfa}
    25532590\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    2554 1 2 3 ®" "®
    2555 \end{cfa}
    2556 
    2557 \item
    2558 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
    2559 \begin{cfa}[mathescape=off,belowskip=0pt]
    2560 sout | sepOn | 1 | 2 | 3 | sepOn | endl;        §\C{// separator at start of line}§
    2561 \end{cfa}
    2562 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    2563  1 2 3
    2564 \end{cfa}
    2565 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2566 sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// locally turn off implicit separator}§
    2567 \end{cfa}
    2568 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    2569 12 3
    2570 \end{cfa}
    2571 
    2572 \item
    2573 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.
    2574 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2575 sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// globally turn off implicit separation}§
    2576 \end{cfa}
    2577 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    2578 123
    2579 \end{cfa}
    2580 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2581 sout | 1 | sepOn | 2 | 3 | endl;                        §\C{// locally turn on implicit separator}§
    2582 \end{cfa}
    2583 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    2584 1 23
    2585 \end{cfa}
    2586 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    2587 sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separation}§
    2588 \end{cfa}
    2589 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    2590 1 2 3
     25911® ®2® ®3 ®" "®
    25912592\end{cfa}
    25922593
     
    26102611
    26112612\item
    2612 The tuple separator can also be turned on and off.
     2613Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
     2614\begin{cfa}[mathescape=off,belowskip=0pt]
     2615sout | sepOn | 1 | 2 | 3 | sepOn | endl;        §\C{// separator at start/end of line}§
     2616\end{cfa}
     2617\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2618® ®1 2 3® ®
     2619\end{cfa}
     2620\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2621sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// locally turn off implicit separator}§
     2622\end{cfa}
     2623\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     262412 3
     2625\end{cfa}
     2626The tuple separator also responses to being turned on and off.
    26132627\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    26142628sout | sepOn | t1 | sepOff | t2 | endl;         §\C{// locally turn on/off implicit separation}§
     
    26182632\end{cfa}
    26192633Notice a tuple seperator starts the line because the next item is a tuple.
     2634
     2635\item
     2636Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.
     2637\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2638sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// globally turn off implicit separation}§
     2639\end{cfa}
     2640\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2641123
     2642\end{cfa}
     2643\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2644sout | 1 | ®sepOn® | 2 | 3 | endl;                      §\C{// locally turn on implicit separator}§
     2645\end{cfa}
     2646\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     26471® ®23
     2648\end{cfa}
     2649\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2650sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separation}§
     2651\end{cfa}
     2652\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     26531 2 3
     2654\end{cfa}
    26202655\end{enumerate}
    26212656
     
    26262661        int x = 1, y = 2, z = 3;
    26272662        sout | x | y | z | endl;
    2628         [int, int] t1 = [1, 2], t2 = [3, 4];
    2629         sout | t1 | t2 | endl;                                          // print tuple
     2663        [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ];
     2664        sout | t1 | t2 | endl;                                          // print tuples
    26302665        sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
    26312666        sout | 1 | 2 | 3 | endl;
     
    51895224
    51905225
    5191 \section{\protect\CFA Keywords}
     5226\section{\CFA Keywords}
    51925227\label{s:CFAKeywords}
    51935228
     
    54875522For an increase in storage size, new storage after the copied data may be filled.
    54885523\item[alignment]
    5489 an allocation starts on a specified memory boundary, e.g., an address multiple of 64 or 128 for cache-line purposes.
     5524an allocation starts on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes.
    54905525\item[array]
    54915526the allocation size is scaled to the specified number of array elements.
  • src/CodeGen/CodeGenerator.cc

    r11dbfe1 r67fa9f9  
    288288        }
    289289
    290         void CodeGenerator::printDesignators( std::list< Expression * > & designators ) {
    291                 typedef std::list< Expression * > DesignatorList;
     290        void CodeGenerator::visit( Designation * designation ) {
     291                std::list< Expression * > designators = designation->get_designators();
    292292                if ( designators.size() == 0 ) return;
    293                 for ( DesignatorList::iterator iter = designators.begin(); iter != designators.end(); ++iter ) {
    294                         if ( dynamic_cast< NameExpr * >( *iter ) ) {
    295                                 // if expression is a name, then initializing aggregate member
     293                for ( Expression * des : designators ) {
     294                        if ( dynamic_cast< NameExpr * >( des ) || dynamic_cast< VariableExpr * >( des ) ) {
     295                                // if expression is a NameExpr or VariableExpr, then initializing aggregate member
    296296                                output << ".";
    297                                 (*iter)->accept( *this );
     297                                des->accept( *this );
    298298                        } else {
    299                                 // if not a simple name, it has to be a constant expression, i.e. an array designator
     299                                // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt
    300300                                output << "[";
    301                                 (*iter)->accept( *this );
     301                                des->accept( *this );
    302302                                output << "]";
    303303                        } // if
     
    307307
    308308        void CodeGenerator::visit( SingleInit * init ) {
    309                 printDesignators( init->get_designators() );
    310309                init->get_value()->accept( *this );
    311310        }
    312311
    313312        void CodeGenerator::visit( ListInit * init ) {
    314                 printDesignators( init->get_designators() );
     313                auto initBegin = init->begin();
     314                auto initEnd = init->end();
     315                auto desigBegin = init->get_designations().begin();
     316                auto desigEnd = init->get_designations().end();
     317
    315318                output << "{ ";
    316                 genCommaList( init->begin(), init->end() );
     319                for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
     320                        (*desigBegin)->accept( *this );
     321                        (*initBegin)->accept( *this );
     322                        ++initBegin, ++desigBegin;
     323                        if ( initBegin != initEnd ) {
     324                                output << ", ";
     325                        }
     326                }
    317327                output << " }";
     328                assertf( initBegin == initEnd && desigBegin == desigEnd, "Initializers and designators not the same length. %s", toString( init ).c_str() );
    318329        }
    319330
     
    716727
    717728        void CodeGenerator::visit( TypeExpr * typeExpr ) {
    718                 assertf( ! genC, "TypeExpr should not reach code generation." );
    719                 output<< genType( typeExpr->get_type(), "", pretty, genC );
     729                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
     730                // assertf( ! genC, "TypeExpr should not reach code generation." );
     731                if ( ! genC ) {
     732                        output<< genType( typeExpr->get_type(), "", pretty, genC );
     733                }
    720734        }
    721735
  • src/CodeGen/CodeGenerator.h

    r11dbfe1 r67fa9f9  
    4747
    4848                //*** Initializer
     49                virtual void visit( Designation * );
    4950                virtual void visit( SingleInit * );
    5051                virtual void visit( ListInit * );
     
    137138                bool lineMarks = false;
    138139
    139                 void printDesignators( std::list< Expression * > & );
    140140                void handleStorageClass( DeclarationWithType *decl );
    141141                void handleAggregate( AggregateDecl *aggDecl, const std::string & kind );
  • src/Common/PassVisitor.h

    r11dbfe1 r67fa9f9  
    1212#include "SynTree/Expression.h"
    1313#include "SynTree/Constant.h"
     14#include "SynTree/TypeSubstitution.h"
    1415
    1516#include "PassVisitor.proto.h"
     
    2627//                          stmtsToAddBefore or stmtsToAddAfter respectively.
    2728// | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children
    28 // | WithScopes           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
     29// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
    2930//                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
    3031//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    3233class PassVisitor final : public Visitor, public Mutator {
    3334public:
    34         PassVisitor() = default;
    3535
    3636        template< typename... Args >
     
    257257
    258258        void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); }
    259 
    260         guard_value_impl init_guard() {
    261                 guard_value_impl guard;
    262                 auto at_cleanup = at_cleanup_impl(pass, 0);
    263                 if( at_cleanup ) {
    264                         *at_cleanup = [&guard]( cleanup_func_t && func, void* val ) {
    265                                 guard.push( std::move( func ), val );
    266                         };
    267                 }
    268                 return guard;
    269         }
    270259};
    271260
     
    283272
    284273public:
    285         TypeSubstitution * env;
     274        TypeSubstitution * env = nullptr;
    286275};
    287276
     
    295284        std::list< Statement* > stmtsToAddAfter;
    296285};
     286
     287class WithDeclsToAdd {
     288protected:
     289        WithDeclsToAdd() = default;
     290        ~WithDeclsToAdd() = default;
     291
     292public:
     293        std::list< Declaration* > declsToAddBefore;
     294        std::list< Declaration* > declsToAddAfter;
     295};
     296
    297297class WithShortCircuiting {
    298298protected:
     
    304304};
    305305
    306 class WithScopes {
    307 protected:
    308         WithScopes() = default;
    309         ~WithScopes() = default;
     306class WithGuards {
     307protected:
     308        WithGuards() = default;
     309        ~WithGuards() = default;
    310310
    311311public:
     
    318318                }, static_cast< void * >( & val ) );
    319319        }
     320
     321        template< typename T >
     322        void GuardScope( T& val ) {
     323                val.beginScope();
     324                at_cleanup( []( void * val ) {
     325                        static_cast< T * >( val )->endScope();
     326                }, static_cast< void * >( & val ) );
     327        }
     328
     329        template< typename Func >
     330        void GuardAction( Func func ) {
     331                at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
     332        }
    320333};
    321334
     
    323336class WithVisitorRef {
    324337protected:
    325         WithVisitorRef() = default;
    326         ~WithVisitorRef() = default;
    327 
    328 public:
    329         PassVisitor<pass_type> * const visitor;
     338        WithVisitorRef() {}
     339        ~WithVisitorRef() {}
     340
     341public:
     342        PassVisitor<pass_type> * const visitor = nullptr;
    330343};
    331344
  • src/Common/PassVisitor.impl.h

    r11dbfe1 r67fa9f9  
    33#define VISIT_START( node )                     \
    44        __attribute__((unused))                   \
    5         const auto & guard = init_guard();        \
     5        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
    66        bool visit_children = true;               \
    77        set_visit_children( visit_children );   \
     
    1515#define MUTATE_START( node )                    \
    1616        __attribute__((unused))                   \
    17         const auto & guard = init_guard();        \
     17        guard_value_impl guard( at_cleanup_impl(pass, 0) );       \
    1818        bool visit_children = true;               \
    1919        set_visit_children( visit_children );   \
     
    6868        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    6969                // splice in new declarations after previous decl
    70                 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 
     70                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
    7171
    7272                if ( i == decls.end() ) break;
     
    8888        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    8989                // splice in new declarations after previous decl
    90                 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 
     90                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
    9191
    9292                if ( i == decls.end() ) break;
     
    104104void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
    105105        SemanticError errors;
     106
     107        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     108        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
     109        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
     110        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
     111        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
    106112
    107113        StmtList_t* beforeStmts = get_beforeStmts();
     
    181187Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
    182188        return handleStatement( stmt, [this]( Statement * stmt ) {
    183                 maybeAccept( stmt, *this ); 
     189                maybeAccept( stmt, *this );
    184190                return stmt;
    185191        });
     
    212218                expr->accept( *this );
    213219                return expr;
    214         });             
     220        });
    215221}
    216222
     
    565571        VISIT_START( node );
    566572
     573        // maybeAccept( node->get_env(), *this );
     574        maybeAccept( node->get_result(), *this );
     575
    567576        for ( auto expr : node->get_args() ) {
    568577                visitExpression( expr );
     
    575584Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    576585        MUTATE_START( node );
     586
     587        node->set_env( maybeMutate( node->get_env(), *this ) );
     588        node->set_result( maybeMutate( node->get_result(), *this ) );
    577589
    578590        for ( auto& expr : node->get_args() ) {
  • src/Common/PassVisitor.proto.h

    r11dbfe1 r67fa9f9  
    55
    66typedef std::function<void( void * )> cleanup_func_t;
     7typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
    78
    89class guard_value_impl {
    910public:
    10         guard_value_impl() = default;
     11        guard_value_impl( at_cleanup_t * at_cleanup ) {
     12                if( at_cleanup ) {
     13                        *at_cleanup = [this]( cleanup_func_t && func, void* val ) {
     14                                push( std::move( func ), val );
     15                        };
     16                }
     17        }
    1118
    1219        ~guard_value_impl() {
     
    3340};
    3441
    35 typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
    3642
    3743class bool_ref {
     
    5662// Deep magic (a.k.a template meta programming) to make the templated visitor work
    5763// Basically the goal is to make 2 previsit_impl
    58 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
     64// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    5965//     'pass.previsit( node )' that compiles will be used for that node for that type
    6066//     This requires that this option only compile for passes that actually define an appropriate visit.
  • src/Common/utility.h

    r11dbfe1 r67fa9f9  
    305305// for ( val : group_iterate( container1, container2, ... ) ) {}
    306306// syntax to have a for each that iterates multiple containers of the same length
    307 // TODO: update to use variadic arguments
     307// TODO: update to use variadic arguments, perfect forwarding
    308308
    309309template< typename T1, typename T2 >
  • src/ControlStruct/ExceptTranslate.cc

    r11dbfe1 r67fa9f9  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jun 22 15:57:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Fri Jun 30 13:30:00 2017
     13// Update Count     : 1
    1414//
    1515
    1616#include "ExceptTranslate.h"
    1717#include "Common/PassVisitor.h"
    18 
    19 namespace ControlFlow {
     18#include "SynTree/Statement.h"
     19#include "SynTree/Declaration.h"
     20#include "SynTree/Expression.h"
     21#include "SynTree/Type.h"
     22#include "SynTree/Attribute.h"
     23
     24namespace ControlStruct {
    2025
    2126        // This (large) section could probably be moved out of the class
     
    2429        // Type(Qualifiers &, false, std::list<Attribute *> &)
    2530
    26         // void (*function)()
    27         static FunctionType void_func_t(Type::Qualifiers(), false);
     31        // void (*function)();
     32        static FunctionType try_func_t(Type::Qualifiers(), false);
    2833        // void (*function)(int, exception);
    2934        static FunctionType catch_func_t(Type::Qualifiers(), false);
     
    3237        // bool (*function)(exception);
    3338        static FunctionType handle_func_t(Type::Qualifiers(), false);
     39        // void (*function)(__attribute__((unused)) void *);
     40        static FunctionType finally_func_t(Type::Qualifiers(), false);
    3441
    3542        static void init_func_types() {
    36                 static init_complete = false;
     43                static bool init_complete = false;
    3744                if (init_complete) {
    3845                        return;
    3946                }
    4047                ObjectDecl index_obj(
    41                         "index_t",
     48                        "__handler_index",
    4249                        Type::StorageClasses(),
    4350                        LinkageSpec::Cforall,
    4451                        /*bitfieldWidth*/ NULL,
    45                         new BasicType(emptyQualifiers, BasicType::UnsignedInt),
     52                        new BasicType( emptyQualifiers, BasicType::SignedInt ),
    4653                        /*init*/ NULL
    47                 );
     54                        );
    4855                ObjectDecl exception_obj(
    49                         "exception_t",
     56                        "__exception_inst",
    5057                        Type::StorageClasses(),
    5158                        LinkageSpec::Cforall,
    5259                        /*bitfieldWidth*/ NULL,
    53                         new BasicType(emptyQualifiers, BasicType::UnsignedInt),
     60                        new PointerType(
     61                                emptyQualifiers,
     62                                new BasicType( emptyQualifiers, BasicType::SignedInt )
     63                                ),
    5464                        /*init*/ NULL
    55                 );
     65                        );
    5666                ObjectDecl bool_obj(
    57                         "bool_t",
     67                        "__ret_bool",
    5868                        Type::StorageClasses(),
    5969                        LinkageSpec::Cforall,
     
    6171                        new BasicType(emptyQualifiers, BasicType::Bool),
    6272                        /*init*/ NULL
    63                 );
    64 
    65                 catch_func_t.get_parameters().push_back(index_obj.clone());
    66                 catch_func_t.get_parameters().push_back(exception_obj.clone());
    67                 match_func_t.get_returnVals().push_back(index_obj.clone());
    68                 match_func_t.get_parameters().push_back(exception_obj.clone());
    69                 handle_func_t.get_returnVals().push_back(bool_obj.clone());
    70                 handle_func_t.get_parameters().push_back(exception_obj.clone());
     73                        );
     74                ObjectDecl voidptr_obj(
     75                        "__hook",
     76                        Type::StorageClasses(),
     77                        LinkageSpec::Cforall,
     78                        NULL,
     79                        new PointerType(
     80                                emptyQualifiers,
     81                                new VoidType(
     82                                        emptyQualifiers
     83                                        ),
     84                                std::list<Attribute *>{new Attribute("unused")}
     85                                ),
     86                        NULL
     87                        );
     88
     89                catch_func_t.get_parameters().push_back( index_obj.clone() );
     90                catch_func_t.get_parameters().push_back( exception_obj.clone() );
     91                match_func_t.get_returnVals().push_back( index_obj.clone() );
     92                match_func_t.get_parameters().push_back( exception_obj.clone() );
     93                handle_func_t.get_returnVals().push_back( bool_obj.clone() );
     94                handle_func_t.get_parameters().push_back( exception_obj.clone() );
     95                finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
    7196
    7297                init_complete = true;
     
    78103
    79104        void split( CatchList& allHandlers, CatchList& terHandlers,
    80                     CatchList& resHandlers ) {
     105                                CatchList& resHandlers ) {
    81106                while ( !allHandlers.empty() ) {
    82                         Statement * stmt = allHandlers.front();
     107                        CatchStmt * stmt = allHandlers.front();
    83108                        allHandlers.pop_front();
    84                         if (CaseStmt::Terminate == stmt->get_kind()) {
     109                        if (CatchStmt::Terminate == stmt->get_kind()) {
    85110                                terHandlers.push_back(stmt);
    86111                        } else {
     
    92117        template<typename T>
    93118        void free_all( std::list<T *> &list ) {
    94                 std::list<T *>::iterator it;
     119                typename std::list<T *>::iterator it;
    95120                for ( it = list.begin() ; it != list.end() ; ++it ) {
    96121                        delete *it;
     
    100125
    101126        void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
    102                 block->push_back(new DeclStmt(no_labels, item));
    103         }
    104 
    105         Expression * nameOf( FunctionDecl * function ) {
    106                 return new VariableExpr( function );
     127                block->push_back(new DeclStmt(noLabels, item));
     128        }
     129
     130        Expression * nameOf( DeclarationWithType * decl ) {
     131                return new VariableExpr( decl );
    107132        }
    108133
    109134        // ThrowStmt Mutation Helpers
    110135
    111         Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
    112                 // __throw_terminate( EXPR );
    113                 ApplicationExpr * call = new ApplicationExpr( /* ... */ );
    114                 call->get_args.push_back( throwStmt->get_expr() );
    115                 Statement * result = new ExprStmt( throwStmt->get_labels(), call );
     136        Statement * create_given_throw(
     137                        const char * throwFunc, ThrowStmt * throwStmt ) {
     138                // { int NAME = EXPR; throwFunc( &NAME ); }
     139                CompoundStmt * result = new CompoundStmt( noLabels );
     140                ObjectDecl * local = new ObjectDecl(
     141                        "__local_exception_copy",
     142                        Type::StorageClasses(),
     143                        LinkageSpec::Cforall,
     144                        NULL,
     145                        new BasicType( emptyQualifiers, BasicType::SignedInt ),
     146                        new SingleInit( throwStmt->get_expr() )
     147                        );
     148                appendDeclStmt( result, local );
     149                UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
     150                call->get_args().push_back( new AddressExpr( nameOf( local ) ) );
     151                result->push_back( new ExprStmt( throwStmt->get_labels(), call ) );
    116152                throwStmt->set_expr( nullptr );
    117153                delete throwStmt;
    118154                return result;
    119155        }
     156
     157        Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
     158                // { int NAME = EXPR; __throw_terminate( &NAME ); }
     159                return create_given_throw( "__cfaehm__throw_termination", throwStmt );
     160        }
    120161        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
    121162                // __rethrow_terminate();
     163                assert( nullptr == throwStmt->get_expr() );
    122164                Statement * result = new ExprStmt(
    123165                        throwStmt->get_labels(),
    124                         new ApplicationExpr( /* ... */ );
     166                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) )
    125167                        );
    126168                delete throwStmt;
     
    129171        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    130172                // __throw_resume( EXPR );
    131                 ApplicationExpr * call = new ApplicationExpr( /* ... */ );
    132                 call->get_args.push_back( throwStmt->get_expr() );
    133                 Statement * result = new ExprStmt( throwStmt->get_labels(), call );
    134                 throwStmt->set_expr( nullptr );
    135                 delete throwStmt;
    136                 return result;
     173                return create_given_throw( "__cfaehm__throw_resumption", throwStmt );
    137174        }
    138175        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
     
    140177                Statement * result = new ReturnStmt(
    141178                        throwStmt->get_labels(),
    142                         new ConstantExpr(
    143                                 Constant(
    144                                         new BasicType(
    145                                                 Type::Qualifiers(),
    146                                                 BasicType::Bool
    147                                                 ),
    148                                         "0")
    149                                 )
     179                        new ConstantExpr( Constant::from_bool( false ) )
    150180                        );
    151181                delete throwStmt;
     
    160190                return block;
    161191        }
    162         FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) {
    163                 CompoundStmt * body = base_try->get_block();
    164                 base_try->set_block(nullptr);
    165 
    166                 return new FunctionDecl("try", Type::StorageClasses(),
    167                         LinkageSpec::Cforall, void_func_t, body);
     192        FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
     193
     194                return new FunctionDecl( "try", Type::StorageClasses(),
     195                        LinkageSpec::Cforall, try_func_t.clone(), body );
    168196        }
    169197
    170198        FunctionDecl * create_terminate_catch( CatchList &handlers ) {
    171199                std::list<CaseStmt *> handler_wrappers;
     200
     201                FunctionType *func_type = catch_func_t.clone();
     202                DeclarationWithType * index_obj = func_type->get_parameters().front();
     203        //      DeclarationWithType * except_obj = func_type->get_parameters().back();
    172204
    173205                // Index 1..{number of handlers}
     
    178210                        CatchStmt * handler = *it;
    179211
    180                         std::list<Statement *> core;
    181                         if ( /*the exception is named*/ ) {
    182                                 ObjectDecl * local_except = /* Dynamic case, same */;
    183                                 core->push_back( new DeclStmt( noLabel, local_except ) );
    184                         }
    185                         // Append the provided statement to the handler.
    186                         core->push_back( cur_handler->get_body() );
    187                         // Append return onto the inner block? case stmt list?
    188                         CaseStmt * wrapper = new CaseStmt(
     212                        // INTEGERconstant Version
     213                        // case `index`:
     214                        // {
     215                        //     `handler.body`
     216                        // }
     217                        // return;
     218                        std::list<Statement *> caseBody;
     219                        caseBody.push_back( handler->get_body() );
     220                        handler->set_body( nullptr );
     221                        caseBody.push_back( new ReturnStmt( noLabels, nullptr ) );
     222
     223                        handler_wrappers.push_back( new CaseStmt(
    189224                                noLabels,
    190225                                new ConstantExpr( Constant::from_int( index ) ),
    191                                 core
    192                                 );
    193                         handler_wrappers.push_back(wrapper);
     226                                caseBody
     227                                ) );
    194228                }
    195229                // TODO: Some sort of meaningful error on default perhaps?
     230
     231                std::list<Statement*> stmt_handlers;
     232                while ( !handler_wrappers.empty() ) {
     233                        stmt_handlers.push_back( handler_wrappers.front() );
     234                        handler_wrappers.pop_front();
     235                }
    196236
    197237                SwitchStmt * handler_lookup = new SwitchStmt(
    198238                        noLabels,
    199                         /*parameter 0: index*/,
    200                         handler_wrappers,
    201                         false
     239                        nameOf( index_obj ),
     240                        stmt_handlers
    202241                        );
    203242                CompoundStmt * body = new CompoundStmt( noLabels );
     
    205244
    206245                return new FunctionDecl("catch", Type::StorageClasses(),
    207                         LinkageSpec::Cforall, catch_func_t, body);
     246                        LinkageSpec::Cforall, func_type, body);
    208247        }
    209248
    210249        // Create a single check from a moddified handler.
    211         CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) {
    212                 CompoundStmt * block = new CompoundStmt( noLables );
    213 
    214                 appendDeclStmt( block, modded_handler->get_decl() );
    215 
    216                 // TODO: This is not the actual check.
    217                 LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) );
     250        // except_obj is referenced, modded_handler will be freed.
     251        CompoundStmt *create_single_matcher(
     252                        DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
     253                CompoundStmt * block = new CompoundStmt( noLabels );
     254
     255                // INTEGERconstant Version
     256                assert( nullptr == modded_handler->get_decl() );
     257                ConstantExpr * number =
     258                        dynamic_cast<ConstantExpr*>( modded_handler->get_cond() );
     259                assert( number );
     260                modded_handler->set_cond( nullptr );
     261
     262                Expression * cond;
     263                {
     264                        std::list<Expression *> args;
     265                        args.push_back( number );
     266
     267                        std::list<Expression *> rhs_args;
     268                        rhs_args.push_back( nameOf( except_obj ) );
     269                        Expression * rhs = new UntypedExpr(
     270                                new NameExpr( "*?" ), rhs_args );
     271                        args.push_back( rhs );
     272
     273                        cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args );
     274                }
    218275
    219276                if ( modded_handler->get_cond() ) {
    220                         cond = new LogicalExpr( cond, modded_handler->get_cond() )q
     277                        cond = new LogicalExpr( cond, modded_handler->get_cond() );
    221278                }
    222279                block->push_back( new IfStmt( noLabels,
    223                         cond, modded_handler->get_body() );
     280                        cond, modded_handler->get_body(), nullptr ) );
    224281
    225282                modded_handler->set_decl( nullptr );
     
    232289        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    233290                CompoundStmt * body = new CompoundStmt( noLabels );
     291
     292                FunctionType * func_type = match_func_t.clone();
     293                DeclarationWithType * except_obj = func_type->get_parameters().back();
    234294
    235295                // Index 1..{number of handlers}
     
    240300                        CatchStmt * handler = *it;
    241301
    242                         // body should have been taken by create_terminate_catch.
    243                         // assert( nullptr == handler->get_body() );
     302                        // Body should have been taken by create_terminate_catch.
     303                        assert( nullptr == handler->get_body() );
     304
     305                        // Create new body.
    244306                        handler->set_body( new ReturnStmt( noLabels,
    245307                                new ConstantExpr( Constant::from_int( index ) ) ) );
    246308
    247                         body->push_back( create_single_matcher( handler ) );
    248                 }
     309                        // Create the handler.
     310                        body->push_back( create_single_matcher( except_obj, handler ) );
     311                        *it = nullptr;
     312                }
     313
     314                body->push_back( new ReturnStmt( noLabels, new ConstantExpr(
     315                        Constant::from_int( 0 ) ) ) );
    249316
    250317                return new FunctionDecl("match", Type::StorageClasses(),
    251                         LinkageSpec::Cforall, match_func_t, body);
    252         }
    253 
    254         Statement * create_terminate_caller(
     318                        LinkageSpec::Cforall, func_type, body);
     319        }
     320
     321        CompoundStmt * create_terminate_caller(
    255322                        FunctionDecl * try_wrapper,
    256323                        FunctionDecl * terminate_catch,
    257324                        FunctionDecl * terminate_match) {
    258325
    259                 ApplicationExpr * caller = new ApplicationExpr( /* ... */ );
    260                 std::list<Expression *>& args = caller.get_args();
     326                UntypedExpr * caller = new UntypedExpr( new NameExpr(
     327                        "__cfaehm__try_terminate" ) );
     328                std::list<Expression *>& args = caller->get_args();
    261329                args.push_back( nameOf( try_wrapper ) );
    262330                args.push_back( nameOf( terminate_catch ) );
    263331                args.push_back( nameOf( terminate_match ) );
    264332
    265                 return new ExprStmt( noLabels, caller );
     333                CompoundStmt * callStmt = new CompoundStmt( noLabels );
     334                callStmt->push_back( new ExprStmt( noLabels, caller ) );
     335                return callStmt;
    266336        }
    267337
    268338        FunctionDecl * create_resume_handler( CatchList &handlers ) {
    269                 CompoundStmt * body = new CompountStmt( noLabels );
     339                CompoundStmt * body = new CompoundStmt( noLabels );
     340
     341                FunctionType * func_type = match_func_t.clone();
     342                DeclarationWithType * except_obj = func_type->get_parameters().back();
    270343
    271344                CatchList::iterator it;
     
    280353                                handling_code->push_back( handler->get_body() );
    281354                        }
    282                         handling_code->push_back( new ReturnStmt( noLabel,
     355                        handling_code->push_back( new ReturnStmt( noLabels,
    283356                                new ConstantExpr( Constant::from_bool( false ) ) ) );
    284357                        handler->set_body( handling_code );
    285358
    286359                        // Create the handler.
    287                         body->push_back( create_single_matcher( handler ) );
     360                        body->push_back( create_single_matcher( except_obj, handler ) );
     361                        *it = nullptr;
    288362                }
    289363
    290364                return new FunctionDecl("handle", Type::StorageClasses(),
    291                         LinkageSpec::Cforall, handle_func_t, body);
    292         }
    293 
    294         Statement * create_resume_wrapper(
     365                        LinkageSpec::Cforall, func_type, body);
     366        }
     367
     368        CompoundStmt * create_resume_wrapper(
     369                        StructDecl * node_decl,
    295370                        Statement * wraps,
    296371                        FunctionDecl * resume_handler ) {
    297372                CompoundStmt * body = new CompoundStmt( noLabels );
    298373
    299                 // struct node = {current top resume handler, call to resume_handler};
    300                 // __attribute__((cleanup( ... )));
    301                 // set top resume handler to node.
    302                 // The wrapped statement.
    303 
    304                 ListInit * node_init;
    305                 {
    306                         std::list<Initializer*> field_inits;
    307                         field_inits.push_back( new SingleInit( /* ... */ ) );
    308                         field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) );
    309                         node_init = new ListInit( field_inits );
    310                 }
     374                // struct __try_resume_node __resume_node
     375                //      __attribute__((cleanup( __cfaehm__try_resume_cleanup )));
     376                // ** unwinding of the stack here could cause problems **
     377                // ** however I don't think that can happen currently **
     378                // __cfaehm__try_resume_setup( &__resume_node, resume_handler );
    311379
    312380                std::list< Attribute * > attributes;
    313381                {
    314382                        std::list< Expression * > attr_params;
    315                         attr_params.push_back( nameOf( /* ... deconstructor ... */ ) );
    316                         attrributes.push_back( new Attribute( "cleanup", attr_params ) );
    317                 }
    318 
    319                 appendDeclStmt( body,
    320                 /**/ ObjectDecl(
    321                         "resume_node",
     383                        attr_params.push_back( new NameExpr(
     384                                "__cfaehm__try_resume_cleanup" ) );
     385                        attributes.push_back( new Attribute( "cleanup", attr_params ) );
     386                }
     387
     388                ObjectDecl * obj = new ObjectDecl(
     389                        "__resume_node",
    322390                        Type::StorageClasses(),
    323391                        LinkageSpec::Cforall,
    324392                        nullptr,
    325                         /* Type* = resume_node */,
    326                         node_init,
     393                        new StructInstType(
     394                                Type::Qualifiers(),
     395                                node_decl
     396                                ),
     397                        nullptr,
    327398                        attributes
    328                         )
    329                 );
     399                        );
     400                appendDeclStmt( body, obj );
     401
     402                UntypedExpr *setup = new UntypedExpr( new NameExpr(
     403                        "__cfaehm__try_resume_setup" ) );
     404                setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) );
     405                setup->get_args().push_back( nameOf( resume_handler ) );
     406
     407                body->push_back( new ExprStmt( noLabels, setup ) );
     408
    330409                body->push_back( wraps );
    331410                return body;
     
    333412
    334413        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    335                 CompoundStmt * body = tryStmt->get_finally();
     414                FinallyStmt * finally = tryStmt->get_finally();
     415                CompoundStmt * body = finally->get_block();
     416                finally->set_block( nullptr );
     417                delete finally;
    336418                tryStmt->set_finally( nullptr );
    337419
    338420                return new FunctionDecl("finally", Type::StorageClasses(),
    339                         LinkageSpec::Cforall, void_func_t, body);
    340         }
    341 
    342         ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) {
    343                 // struct _cleanup_hook NAME __attribute__((cleanup( ... )));
     421                        LinkageSpec::Cforall, finally_func_t.clone(), body);
     422        }
     423
     424        ObjectDecl * create_finally_hook(
     425                        StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
     426                // struct __cfaehm__cleanup_hook __finally_hook
     427                //      __attribute__((cleanup( finally_wrapper )));
    344428
    345429                // Make Cleanup Attribute.
     
    348432                        std::list< Expression * > attr_params;
    349433                        attr_params.push_back( nameOf( finally_wrapper ) );
    350                         attrributes.push_back( new Attribute( "cleanup", attr_params ) );
    351                 }
    352 
    353                 return ObjectDecl( /* ... */
    354                         const std::string &name "finally_hook",
     434                        attributes.push_back( new Attribute( "cleanup", attr_params ) );
     435                }
     436
     437                return new ObjectDecl(
     438                        "__finally_hook",
    355439                        Type::StorageClasses(),
    356440                        LinkageSpec::Cforall,
    357441                        nullptr,
    358                         /* ... Type * ... */,
     442                        new StructInstType(
     443                                emptyQualifiers,
     444                                hook_decl
     445                                ),
    359446                        nullptr,
    360447                        attributes
     
    363450
    364451
    365         class ExceptionMutatorCore : public WithScoping {
     452        class ExceptionMutatorCore : public WithGuards {
    366453                enum Context { NoHandler, TerHandler, ResHandler };
    367454
     
    370457                // loop, switch or the goto stays within the function.
    371458
    372                 Context curContext;
     459                Context cur_context;
    373460
    374461                // We might not need this, but a unique base for each try block's
     
    377464                //unsigned int try_count = 0;
    378465
     466                StructDecl *node_decl;
     467                StructDecl *hook_decl;
    379468
    380469        public:
    381470                ExceptionMutatorCore() :
    382                         curContext(NoHandler)
     471                        cur_context(NoHandler),
     472                        node_decl(nullptr), hook_decl(nullptr)
    383473                {}
    384474
    385                 void premutate( CatchStmt *tryStmt );
     475                void premutate( CatchStmt *catchStmt );
     476                void premutate( StructDecl *structDecl );
    386477                Statement * postmutate( ThrowStmt *throwStmt );
    387478                Statement * postmutate( TryStmt *tryStmt );
     
    393484                        if ( throwStmt->get_expr() ) {
    394485                                return create_terminate_throw( throwStmt );
    395                         } else if ( TerHandler == curContext ) {
     486                        } else if ( TerHandler == cur_context ) {
    396487                                return create_terminate_rethrow( throwStmt );
    397488                        } else {
    398489                                assertf(false, "Invalid throw in %s at %i\n",
    399                                         throwStmt->location.filename,
     490                                        throwStmt->location.filename.c_str(),
    400491                                        throwStmt->location.linenumber);
    401492                                return nullptr;
     
    404495                        if ( throwStmt->get_expr() ) {
    405496                                return create_resume_throw( throwStmt );
    406                         } else if ( ResHandler == curContext ) {
     497                        } else if ( ResHandler == cur_context ) {
    407498                                return create_resume_rethrow( throwStmt );
    408499                        } else {
    409500                                assertf(false, "Invalid throwResume in %s at %i\n",
    410                                         throwStmt->location.filename,
     501                                        throwStmt->location.filename.c_str(),
    411502                                        throwStmt->location.linenumber);
    412503                                return nullptr;
     
    416507
    417508        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
     509                assert( node_decl );
     510                assert( hook_decl );
     511
    418512                // Generate a prefix for the function names?
    419513
    420                 CompoundStmt * block = new CompoundStmt();
    421                 Statement * inner = take_try_block( tryStmt );
     514                CompoundStmt * block = new CompoundStmt( noLabels );
     515                CompoundStmt * inner = take_try_block( tryStmt );
    422516
    423517                if ( tryStmt->get_finally() ) {
     
    427521                        appendDeclStmt( block, finally_block );
    428522                        // Create and add the finally cleanup hook.
    429                         appendDeclStmt( block, create_finally_hook( finally_block ) );
    430                 }
    431 
    432                 StatementList termination_handlers;
    433                 StatementList resumption_handlers;
    434                 split( tryStmt->get_handlers(),
    435                        termination_handlers, resumption_handlers );
    436 
    437                 if ( resumeption_handlers.size() ) {
     523                        appendDeclStmt( block,
     524                                create_finally_hook( hook_decl, finally_block ) );
     525                }
     526
     527                CatchList termination_handlers;
     528                CatchList resumption_handlers;
     529                split( tryStmt->get_catchers(),
     530                           termination_handlers, resumption_handlers );
     531
     532                if ( resumption_handlers.size() ) {
    438533                        // Define the helper function.
    439534                        FunctionDecl * resume_handler =
     
    441536                        appendDeclStmt( block, resume_handler );
    442537                        // Prepare hooks
    443                         inner = create_resume_wrapper( inner, resume_handler );
     538                        inner = create_resume_wrapper( node_decl, inner, resume_handler );
    444539                }
    445540
     
    462557                block->push_back( inner );
    463558
    464                 free_all( termination_handlers );
    465                 free_all( resumption_handlers );
     559                //free_all( termination_handlers );
     560                //free_all( resumption_handlers );
    466561
    467562                return block;
     
    469564
    470565        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    471                 GuardValue( curContext );
    472                 if ( CatchStmt::Termination == catchStmt->get_kind() ) {
    473                         curContext = TerHandler;
     566                GuardValue( cur_context );
     567                if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
     568                        cur_context = TerHandler;
    474569                } else {
    475                         curContext = ResHandler;
    476                 }
    477         }
    478 
    479     void translateEHM( std::list< Declaration *> & translationUnit ) {
     570                        cur_context = ResHandler;
     571                }
     572        }
     573
     574        void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
     575                if ( !structDecl->has_body() ) {
     576                        // Skip children?
     577                        return;
     578                } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
     579                        assert( nullptr == node_decl );
     580                        node_decl = structDecl;
     581                } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
     582                        assert( nullptr == hook_decl );
     583                        hook_decl = structDecl;
     584                }
     585                // Later we might get the exception type as well.
     586        }
     587
     588        void translateEHM( std::list< Declaration *> & translationUnit ) {
     589                init_func_types();
     590
    480591                PassVisitor<ExceptionMutatorCore> translator;
    481592                for ( Declaration * decl : translationUnit ) {
    482                         decl->mutate( translator );
     593                        decl->acceptMutator( translator );
    483594                }
    484595        }
  • src/ControlStruct/ExceptTranslate.h

    r11dbfe1 r67fa9f9  
    1010// Created On       : Tus Jun 06 10:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jun 22 15:57:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Fri Jun 30 10:20:00 2017
     13// Update Count     : 2
    1414//
    1515
     
    1717#define EXCEPT_TRANSLATE_H
    1818
    19 namespace ControlFlow {
     19#include <list>
     20#include "SynTree/SynTree.h"
     21
     22namespace ControlStruct {
    2023        void translateEHM( std::list< Declaration *> & translationUnit );
    2124        /* Converts exception handling structures into their underlying C code.
  • src/ControlStruct/module.mk

    r11dbfe1 r67fa9f9  
    1010## Author           : Richard C. Bilson
    1111## Created On       : Mon Jun  1 17:49:17 2015
    12 ## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Thu Aug  4 11:38:06 2016
    14 ## Update Count     : 3
     12## Last Modified By : Andrew Beach
     13## Last Modified On : Wed Jun 28 16:15:00 2017
     14## Update Count     : 4
    1515###############################################################################
    1616
    1717SRC +=  ControlStruct/LabelGenerator.cc \
    1818        ControlStruct/LabelFixer.cc \
    19         ControlStruct/MLEMutator.cc \
     19        ControlStruct/MLEMutator.cc \
    2020        ControlStruct/Mutate.cc \
    21         ControlStruct/ForExprMutator.cc
    22 
     21        ControlStruct/ForExprMutator.cc \
     22        ControlStruct/ExceptTranslate.cc
  • src/GenPoly/Box.cc

    r11dbfe1 r67fa9f9  
    504504                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    505505                        if ( functionDecl->get_statements() ) {         // empty routine body ?
     506                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506507                                doBeginScope();
    507508                                scopeTyVars.beginScope();
     
    548549                                retval = oldRetval;
    549550                                doEndScope();
     551                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    550552                        } // if
    551553                        return functionDecl;
     
    11161118
    11171119                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    1118                         // std::cerr << "mutate appExpr: ";
     1120                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11191121                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    11201122                        //      std::cerr << i->first << " ";
     
    11411143                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
    11421144
     1145                        // std::cerr << function << std::endl;
     1146                        // std::cerr << "scopeTyVars: ";
     1147                        // printTyVarMap( std::cerr, scopeTyVars );
     1148                        // std::cerr << "exprTyVars: ";
     1149                        // printTyVarMap( std::cerr, exprTyVars );
     1150                        // std::cerr << "env: " << *env << std::endl;
     1151                        // std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl;
     1152
    11431153                        // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr
    11441154                        // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int))
    11451155                        // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome.
    11461156                        if ( dynRetType ) {
     1157                                // std::cerr << "dynRetType: " << dynRetType << std::endl;
    11471158                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    11481159                                ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
  • src/GenPoly/InstantiateGeneric.cc

    r11dbfe1 r67fa9f9  
    2222#include "InstantiateGeneric.h"
    2323
    24 #include "DeclMutator.h"
    2524#include "GenPoly.h"
    2625#include "ScopedSet.h"
    2726#include "ScrubTyVars.h"
    28 #include "PolyMutator.h"
     27
     28#include "Common/PassVisitor.h"
     29#include "Common/ScopedMap.h"
     30#include "Common/UniqueName.h"
     31#include "Common/utility.h"
    2932
    3033#include "ResolvExpr/typeops.h"
     
    3437#include "SynTree/Type.h"
    3538
    36 #include "Common/ScopedMap.h"
    37 #include "Common/UniqueName.h"
    38 #include "Common/utility.h"
     39
     40#include "InitTweak/InitTweak.h"
     41
    3942
    4043namespace GenPoly {
     
    153156        }
    154157
    155         // collect the environments of each TypeInstType so that type variables can be replaced
    156         // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.
    157         class EnvFinder final : public GenPoly::PolyMutator {
    158         public:
    159                 using GenPoly::PolyMutator::mutate;
    160                 virtual Type * mutate( TypeInstType * inst ) override {
    161                         if ( env ) envMap[inst] = env;
    162                         return inst;
    163                 }
    164 
    165                 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?
    166                 virtual Type * mutate( FunctionType * ftype ) override {
    167                         return ftype;
    168                 }
    169                 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;
    170         };
    171 
    172158        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    173         class GenericInstantiator final : public DeclMutator {
     159        struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
    174160                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    175161                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     
    178164                /// Namer for concrete types
    179165                UniqueName typeNamer;
    180                 /// Reference to mapping of environments
    181                 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
    182         public:
    183                 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
    184 
    185                 using DeclMutator::mutate;
    186                 virtual Type* mutate( StructInstType *inst ) override;
    187                 virtual Type* mutate( UnionInstType *inst ) override;
    188 
    189                 virtual void doBeginScope() override;
    190                 virtual void doEndScope() override;
     166                /// Should not make use of type environment to replace types of function parameter and return values.
     167                bool inFunctionType = false;
     168                GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
     169
     170                Type* postmutate( StructInstType *inst );
     171                Type* postmutate( UnionInstType *inst );
     172
     173                void premutate( FunctionType * ftype ) {
     174                        GuardValue( inFunctionType );
     175                        inFunctionType = true;
     176                }
     177
     178                void beginScope();
     179                void endScope();
    191180        private:
    192181                /// Wrap instantiation lookup for structs
     
    207196
    208197        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
    209                 EnvFinder finder;
    210                 mutateAll( translationUnit, finder );
    211                 GenericInstantiator instantiator( finder.envMap );
    212                 instantiator.mutateDeclarationList( translationUnit );
     198                PassVisitor<GenericInstantiator> instantiator;
     199                mutateAll( translationUnit, instantiator );
    213200        }
    214201
     
    306293        Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) {
    307294                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    308                         if ( envMap.count( typeInst ) ) {
    309                                 TypeSubstitution * env = envMap.at( typeInst );
     295                        if ( env && ! inFunctionType ) {
    310296                                Type *concrete = env->lookup( typeInst->get_name() );
    311297                                if ( concrete ) {
     
    331317
    332318
    333         Type* GenericInstantiator::mutate( StructInstType *inst ) {
    334                 // mutate subtypes
    335                 Type *mutated = Mutator::mutate( inst );
    336                 inst = dynamic_cast< StructInstType* >( mutated );
    337                 if ( ! inst ) return mutated;
    338 
     319        Type* GenericInstantiator::postmutate( StructInstType *inst ) {
    339320                // exit early if no need for further mutation
    340321                if ( inst->get_parameters().empty() ) return inst;
     
    368349                                substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    369350                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    370                                 concDecl->acceptMutator( *this ); // recursively instantiate members
    371                                 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
     351                                concDecl->acceptMutator( *visitor ); // recursively instantiate members
     352                                declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
    372353                        }
    373354                        StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    388369        }
    389370
    390         Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    391                 // mutate subtypes
    392                 Type *mutated = Mutator::mutate( inst );
    393                 inst = dynamic_cast< UnionInstType* >( mutated );
    394                 if ( ! inst ) return mutated;
    395 
     371        Type* GenericInstantiator::postmutate( UnionInstType *inst ) {
    396372                // exit early if no need for further mutation
    397373                if ( inst->get_parameters().empty() ) return inst;
     
    423399                                substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    424400                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    425                                 concDecl->acceptMutator( *this ); // recursively instantiate members
    426                                 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
     401                                concDecl->acceptMutator( *visitor ); // recursively instantiate members
     402                                declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
    427403                        }
    428404                        UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    442418        }
    443419
    444         void GenericInstantiator::doBeginScope() {
    445                 DeclMutator::doBeginScope();
     420        void GenericInstantiator::beginScope() {
    446421                instantiations.beginScope();
    447422                dtypeStatics.beginScope();
    448423        }
    449424
    450         void GenericInstantiator::doEndScope() {
    451                 DeclMutator::doEndScope();
     425        void GenericInstantiator::endScope() {
    452426                instantiations.endScope();
    453427                dtypeStatics.endScope();
  • src/InitTweak/FixInit.cc

    r11dbfe1 r67fa9f9  
    104104                        typedef AddStmtVisitor Parent;
    105105                        using Parent::visit;
    106                         typedef std::set< ObjectDecl * > ObjectSet;
     106                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
     107                        typedef std::list< ObjectDecl * > ObjectSet;
    107108                        virtual void visit( CompoundStmt *compoundStmt ) override;
    108109                        virtual void visit( DeclStmt *stmt ) override;
     
    116117
    117118                // debug
    118                 struct printSet {
    119                         typedef ObjDeclCollector::ObjectSet ObjectSet;
    120                         printSet( const ObjectSet & objs ) : objs( objs ) {}
     119                template<typename ObjectSet>
     120                struct PrintSet {
     121                        PrintSet( const ObjectSet & objs ) : objs( objs ) {}
    121122                        const ObjectSet & objs;
    122123                };
    123                 std::ostream & operator<<( std::ostream & out, const printSet & set) {
     124                template<typename ObjectSet>
     125                PrintSet<ObjectSet> printSet( const ObjectSet & objs ) { return PrintSet<ObjectSet>( objs ); }
     126                template<typename ObjectSet>
     127                std::ostream & operator<<( std::ostream & out, const PrintSet<ObjectSet> & set) {
    124128                        out << "{ ";
    125129                        for ( ObjectDecl * obj : set.objs ) {
     
    724728                                                // static bool __objName_uninitialized = true
    725729                                                BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    726                                                 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ), noDesignators );
     730                                                SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) );
    727731                                                ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr );
    728732                                                isUninitializedVar->fixUniqueId();
     
    745749
    746750                                                Statement * dtor = ctorInit->get_dtor();
    747                                                 objDecl->set_init( NULL );
    748                                                 ctorInit->set_ctor( NULL );
     751                                                objDecl->set_init( nullptr );
     752                                                ctorInit->set_ctor( nullptr );
    749753                                                ctorInit->set_dtor( nullptr );
    750754                                                if ( dtor ) {
     
    799803                                                } else {
    800804                                                        stmtsToAddAfter.push_back( ctor );
    801                                                         objDecl->set_init( NULL );
    802                                                         ctorInit->set_ctor( NULL );
     805                                                        objDecl->set_init( nullptr );
     806                                                        ctorInit->set_ctor( nullptr );
    803807                                                }
    804808                                        } // if
    805809                                } else if ( Initializer * init = ctorInit->get_init() ) {
    806810                                        objDecl->set_init( init );
    807                                         ctorInit->set_init( NULL );
     811                                        ctorInit->set_init( nullptr );
    808812                                } else {
    809813                                        // no constructor and no initializer, which is okay
    810                                         objDecl->set_init( NULL );
     814                                        objDecl->set_init( nullptr );
    811815                                } // if
    812816                                delete ctorInit;
     
    816820
    817821                void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {
    818                         std::set< ObjectDecl * > prevVars = curVars;
     822                        ObjectSet prevVars = curVars;
    819823                        Parent::visit( compoundStmt );
    820824                        curVars = prevVars;
     
    824828                        // keep track of all variables currently in scope
    825829                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    826                                 curVars.insert( objDecl );
     830                                curVars.push_back( objDecl );
    827831                        } // if
    828832                        Parent::visit( stmt );
     
    939943                        )
    940944                        if ( ! diff.empty() ) {
     945                                // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.
     946                                std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );
     947
    941948                                // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor
    942949                                OrderedDecls ordered;
    943950                                for ( OrderedDecls & rdo : reverseDeclOrder ) {
    944951                                        // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
    945                                         copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return diff.count( objDecl ); } );
     952                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    946953                                } // for
    947954                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
  • src/InitTweak/GenInit.cc

    r11dbfe1 r67fa9f9  
    4444        }
    4545
    46         class ReturnFixer : public WithStmtsToAdd, public WithScopes {
    47           public:
     46        struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
    4847                /// consistently allocates a temporary variable for the return value
    4948                /// of a function so that anything which the resolver decides can be constructed
     
    5958        };
    6059
    61         class CtorDtor final : public GenPoly::PolyMutator {
    62           public:
    63                 typedef GenPoly::PolyMutator Parent;
    64                 using Parent::mutate;
     60        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6561                /// create constructor and destructor statements for object declarations.
    6662                /// the actual call statements will be added in after the resolver has run
     
    6965                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
    7066
    71                 virtual DeclarationWithType * mutate( ObjectDecl * ) override;
    72                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     67                void previsit( ObjectDecl * );
     68                void previsit( FunctionDecl *functionDecl );
     69
    7370                // should not traverse into any of these declarations to find objects
    7471                // that need to be constructed or destructed
    75                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
    76                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    77                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    78                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    79                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    80                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    81 
    82                 virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
    83 
    84                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
     72                void previsit( StructDecl *aggregateDecl );
     73                void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
     74                void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
     75                void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
     76                void previsit( TypeDecl *typeDecl ) { visit_children = false; }
     77                void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
     78
     79                void previsit( FunctionType *funcType ) { visit_children = false; }
     80
     81                void previsit( CompoundStmt * compoundStmt );
    8582
    8683          private:
     
    211208
    212209        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    213                 CtorDtor ctordtor;
    214                 mutateAll( translationUnit, ctordtor );
     210                PassVisitor<CtorDtor> ctordtor;
     211                acceptAll( translationUnit, ctordtor );
    215212        }
    216213
     
    289286        }
    290287
    291         DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     288        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    292289                handleDWT( objDecl );
    293290                // hands off if @=, extern, builtin, etc.
     
    301298                        objDecl->set_init( genCtorInit( objDecl ) );
    302299                }
    303                 return Parent::mutate( objDecl );
    304         }
    305 
    306         DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    307                 ValueGuard< bool > oldInFunc = inFunction;
     300        }
     301
     302        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     303                GuardValue( inFunction );
    308304                inFunction = true;
    309305
    310306                handleDWT( functionDecl );
    311307
    312                 managedTypes.beginScope();
     308                GuardScope( managedTypes );
    313309                // go through assertions and recursively add seen ctor/dtors
    314310                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
     
    317313                        }
    318314                }
    319                 // parameters should not be constructed and destructed, so don't mutate FunctionType
    320                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    321 
    322                 managedTypes.endScope();
    323                 return functionDecl;
    324         }
    325 
    326         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
     315
     316                PassVisitor<CtorDtor> newCtorDtor;
     317                newCtorDtor.pass = *this;
     318                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     319                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     320        }
     321
     322        void CtorDtor::previsit( StructDecl *aggregateDecl ) {
     323                visit_children = false; // do not try to construct and destruct aggregate members
     324
    327325                // don't construct members, but need to take note if there is a managed member,
    328326                // because that means that this type is also managed
     
    336334                        }
    337335                }
    338                 return aggregateDecl;
    339         }
    340 
    341         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    342                 managedTypes.beginScope();
    343                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    344                 managedTypes.endScope();
    345                 return stmt;
    346         }
    347 
     336        }
     337
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     339                GuardScope( managedTypes );
     340        }
    348341} // namespace InitTweak
    349342
  • src/InitTweak/InitTweak.cc

    r11dbfe1 r67fa9f9  
    1414                public:
    1515                        bool hasDesignations = false;
    16                         template<typename Init>
    17                         void handleInit( Init * init ) {
    18                                 if ( ! init->get_designators().empty() ) hasDesignations = true;
    19                                 else Visitor::visit( init );
    20                         }
    21                         virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
    22                         virtual void visit( ListInit * listInit ) { handleInit( listInit); }
     16                        virtual void visit( Designation * des ) {
     17                                if ( ! des->get_designators().empty() ) hasDesignations = true;
     18                                else Visitor::visit( des );
     19                        }
    2320                };
    2421
  • src/MakeLibCfa.cc

    r11dbfe1 r67fa9f9  
    9292                assert( ! objDecl->get_init() );
    9393                std::list< Expression* > noDesignators;
    94                 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
     94                objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed
    9595                newDecls.push_back( objDecl );
    9696        }
  • src/Makefile.in

    r11dbfe1 r67fa9f9  
    119119        ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
    120120        ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
     121        ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) \
    121122        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    122123        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
     
    161162        ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
    162163        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
     164        ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
    163165        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    164166        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    394396        ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
    395397        ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
    396         ControlStruct/ForExprMutator.cc GenPoly/Box.cc \
     398        ControlStruct/ForExprMutator.cc \
     399        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    397400        GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
    398401        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
     
    414417        ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \
    415418        ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \
    416         ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \
    417         SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    418         SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    419         SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
    420         SynTree/BasicType.cc SynTree/PointerType.cc \
    421         SynTree/ArrayType.cc SynTree/FunctionType.cc \
    422         SynTree/ReferenceToType.cc SynTree/TupleType.cc \
    423         SynTree/TypeofType.cc SynTree/AttrType.cc \
     419        ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \
     420        SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
     421        SymTab/FixFunction.cc SymTab/ImplementationType.cc \
     422        SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
     423        SynTree/VoidType.cc SynTree/BasicType.cc \
     424        SynTree/PointerType.cc SynTree/ArrayType.cc \
     425        SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
     426        SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
    424427        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    425428        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    592595        ControlStruct/$(DEPDIR)/$(am__dirstamp)
    593596ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT):  \
     597        ControlStruct/$(am__dirstamp) \
     598        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     599ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT):  \
    594600        ControlStruct/$(am__dirstamp) \
    595601        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     
    721727        ResolvExpr/$(am__dirstamp) \
    722728        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     729ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT):  \
     730        ResolvExpr/$(am__dirstamp) \
     731        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    723732SymTab/$(am__dirstamp):
    724733        @$(MKDIR_P) SymTab
     
    853862        -rm -f Common/driver_cfa_cpp-UniqueName.$(OBJEXT)
    854863        -rm -f Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT)
     864        -rm -f ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT)
    855865        -rm -f ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT)
    856866        -rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT)
     
    890900        -rm -f ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT)
    891901        -rm -f ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT)
     902        -rm -f ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT)
    892903        -rm -f ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT)
    893904        -rm -f ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT)
     
    965976@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@
    966977@AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po@am__quote@
     978@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po@am__quote@
    967979@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@
    968980@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
     
    10021014@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@
    10031015@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
     1016@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
    10041017@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    10051018@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
     
    13551368@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
    13561369
     1370ControlStruct/driver_cfa_cpp-ExceptTranslate.o: ControlStruct/ExceptTranslate.cc
     1371@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
     1372@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
     1373@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.o' libtool=no @AMDEPBACKSLASH@
     1374@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1375@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
     1376
     1377ControlStruct/driver_cfa_cpp-ExceptTranslate.obj: ControlStruct/ExceptTranslate.cc
     1378@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
     1379@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
     1380@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.obj' libtool=no @AMDEPBACKSLASH@
     1381@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1382@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
     1383
    13571384GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc
    13581385@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
     
    19421969@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    19431970@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
     1971
     1972ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc
     1973@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
     1974@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
     1975@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.o' libtool=no @AMDEPBACKSLASH@
     1976@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1977@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
     1978
     1979ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc
     1980@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
     1981@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
     1982@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.obj' libtool=no @AMDEPBACKSLASH@
     1983@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1984@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
    19441985
    19451986SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
  • src/Parser/InitializerNode.cc

    r11dbfe1 r67fa9f9  
    7474
    7575        InitializerNode *moreInit;
    76         if  ( get_next() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) != 0) )
     76        if ( (moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) ) {
    7777                moreInit->printOneLine( os );
     78        }
    7879}
    7980
    8081Initializer *InitializerNode::build() const {
    8182        if ( aggregate ) {
     83                // steal designators from children
     84                std::list< Designation * > designlist;
     85                InitializerNode * child = next_init();
     86                for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
     87                        std::list< Expression * > desList;
     88                        buildList< Expression, ExpressionNode >( child->designator, desList );
     89                        designlist.push_back( new Designation( desList ) );
     90                } // for
    8291                std::list< Initializer * > initlist;
    8392                buildList< Initializer, InitializerNode >( next_init(), initlist );
    84 
    85                 std::list< Expression * > designlist;
    86 
    87                 if ( designator != 0 ) {