Ignore:
Timestamp:
Feb 18, 2018, 9:33:18 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
23a1eb7b
Parents:
2b95887 (diff), 29f47139 (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:/u/cforall/software/cfa/cfa-cc

File:
1 edited

Legend:

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

    r2b95887 r370f6ef  
    9090\newcommand*{\etc}{%
    9191        \@ifnextchar{.}{\ETC}%
    92         {\ETC\xspace}%
     92        {\ETC.\xspace}%
    9393}%
    94 \newcommand{\ETAL}{\abbrevFont{et}\hspace{2pt}\abbrevFont{al}}
     94\newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}}
    9595\newcommand*{\etal}{%
    9696        \@ifnextchar{.}{\protect\ETAL}%
    97                 {\abbrevFont{\protect\ETAL}.\xspace}%
     97                {\protect\ETAL.\xspace}%
    9898}%
    9999\newcommand{\VIZ}{\abbrevFont{viz}}
    100100\newcommand*{\viz}{%
    101101        \@ifnextchar{.}{\VIZ}%
    102                 {\abbrevFont{\VIZ}.\xspace}%
     102                {\VIZ.\xspace}%
    103103}%
    104104\makeatother
     
    120120                otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof,
    121121                __typeof__, virtual, with, zero_t},
     122        morekeywords=[2]{
     123                _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, or,
     124                resume, suspend, thread, _Thread_local, waitfor, when, yield},
    122125        moredirectives={defined,include_next}%
    123 }%
     126}
    124127
    125128\lstset{
     
    233236
    234237C already has a limited form of ad-hoc polymorphism in the form of its basic arithmetic operators, which apply to a variety of different types using identical syntax.
    235 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable; Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C.
     238\CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable;
     239Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C.
    236240Code generation for these overloaded functions and variables is implemented by the usual approach of mangling the identifier names to include a representation of their type, while \CFA decides which overload to apply based on the same ``usual arithmetic conversions'' used in C to disambiguate operator overloads.
    237241As an example:
     
    254258The macro wrapping the generic expression imposes some limitations; as an example, it could not implement the example above, because the variables @max@ would collide with the functions @max@.
    255259Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the functions dispatched to, which must all have distinct names.
     260
     261% http://fanf.livejournal.com/144696.html
     262% http://www.robertgamble.net/2012/01/c11-generic-selections.html
     263% https://abissell.com/2014/01/16/c11s-_generic-keyword-macro-applications-and-performance-impacts/
     264
    256265
    257266\subsection{\texorpdfstring{\LstKeywordStyle{forall} Functions}{forall Functions}}
     
    290299void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
    291300                                int (* compar)( const void *, const void * ));
     301
    292302int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 :
    293303                                *(double *)t2 < *(double *)t1 ? 1 : 0; }
     304
    294305double key = 5.0, vals[10] = { /* 10 sorted float values */ };
    295306double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      $\C{// search sorted array}$
     
    300311        int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ }
    301312        return (T *)bsearch( &key, arr, size, sizeof(T), comp ); }
     313
    302314forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
    303315        T * result = bsearch( key, arr, size ); $\C{// call first version}$
    304316        return result ? result - arr : size; }  $\C{// pointer subtraction includes sizeof(T)}$
     317
    305318double * val = bsearch( 5.0, vals, 10 );        $\C{// selection based on return type}$
    306319int posn = bsearch( 5.0, vals, 10 );
     
    311324\CC's type-system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a templated @bsearch@.
    312325
    313 \CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations.
     326\CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations (see Section~\ref{sec:libraries}).
    314327For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@:
    315328\begin{lstlisting}
     
    346359\CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration:
    347360\begin{lstlisting}
    348 trait summable( otype T ) {
     361trait `summable`( otype T ) {
    349362        void ?{}( T *, zero_t );                                $\C{// constructor from 0 literal}$
    350363        T ?+?( T, T );                                                  $\C{// assortment of additions}$
     
    352365        T ++?( T * );
    353366        T ?++( T * ); };
     367
    354368forall( otype T `| summable( T )` ) T sum( T a[$\,$], size_t size ) {  // use trait
    355369        `T` total = { `0` };                                    $\C{// instantiate T from 0 by calling its constructor}$
     
    425439forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; }
    426440forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; }
     441
    427442pair( const char *, int ) p = { "magic", 42 };
    428443int magic = value( p );
     
    11501165@case@ clauses are made disjoint by the @break@ statement.
    11511166While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
    1152 \CFA provides a new control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:
     1167For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:
    11531168\begin{cquote}
    11541169\lstDeleteShortInline@%
     
    11571172\begin{cfa}
    11581173`choose` ( day ) {
    1159   case Mon~Thu:
    1160         // program
    1161 
    1162   case Fri:
    1163         // program
     1174  case Mon~Thu:  // program
     1175
     1176  case Fri:  // program
    11641177        wallet += pay;
    11651178        `fallthrough;`
    1166   case Sat:
    1167         // party
     1179  case Sat:  // party
    11681180        wallet -= party;
    11691181
    1170   case Sun:
    1171         // rest
    1172 
    1173   default:
    1174         // error
     1182  case Sun:  // rest
     1183
     1184  default:  // error
    11751185}
    11761186\end{cfa}
     
    11781188\begin{cfa}
    11791189switch ( day ) {
    1180   case Mon: case Tue: case Wed: case Thu:
    1181         // program
     1190  case Mon: case Tue: case Wed: case Thu:  // program
    11821191        `break;`
    1183   case Fri:
    1184         // program
     1192  case Fri:  // program
    11851193        wallet += pay;
    11861194
    1187   case Sat:
    1188         // party
     1195  case Sat:  // party
    11891196        wallet -= party;
    11901197        `break;`
    1191   case Sun:
    1192         // rest
     1198  case Sun:  // rest
    11931199        `break;`
    1194   default:
    1195         // error
     1200  default:  // error
    11961201}
    11971202\end{cfa}
     
    12281233\label{s:WithClauseStatement}
    12291234
    1230 Grouping heterogenous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:
     1235Grouping heterogeneous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:
    12311236\begin{cfa}
    12321237struct S {                                                                      $\C{// aggregate}$
     
    12431248}
    12441249\end{cfa}
     1250which extends to multiple levels of qualification for nested aggregates.
    12451251A similar situation occurs in object-oriented programming, \eg \CC:
    12461252\begin{C++}
     
    12491255        int i;
    12501256        double d;
    1251         int mem() {                                                             $\C{// implicit "this" parameter}$
     1257        int f() {                                                               $\C{// implicit "this" parameter}$
    12521258                `this->`c; `this->`i; `this->`d;        $\C{// access containing fields}$
    12531259        }
    12541260}
    12551261\end{C++}
    1256 Nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
     1262Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
    12571263However, for other aggregate parameters, qualification is necessary:
    12581264\begin{cfa}
    12591265struct T { double m, n; };
    1260 int C::mem( T & t ) {                                           $\C{// multiple aggregate parameters}$
     1266int C::f( T & t ) {                                                     $\C{// multiple aggregate parameters}$
    12611267        c; i; d;                                                                $\C{\color{red}// this-\textgreater.c, this-\textgreater.i, this-\textgreater.d}$
    12621268        `t.`m; `t.`n;                                                   $\C{// must qualify}$
     
    12641270\end{cfa}
    12651271
    1266 % In object-oriented programming, there is an implicit first parameter, often names @self@ or @this@, which is elided.
    1267 % In any programming language, some functions have a naturally close relationship with a particular data type.
    1268 % Object-oriented programming allows this close relationship to be codified in the language by making such functions \newterm{class methods} of their related data type.
    1269 % Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type.
    1270 % When writing C functions in an object-oriented style, this un-prefixed access is swiftly missed, as access to fields of a @Foo* f@ requires an extra three characters @f->@ every time, which disrupts coding flow and clutters the produced code.
    1271 %
    1272 % \TODO{Fill out section. Be sure to mention arbitrary expressions in with-blocks, recent change driven by Thierry to prioritize field name over parameters.}
    1273 
    1274 To simplify the programmer experience, \CFA provides a @with@ clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers.
     1272To simplify the programmer experience, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers.
    12751273Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block.
    12761274\begin{cfa}
    1277 void f( S s ) `with( s )` {                                     $\C{// with clause}$
    1278         c; i; d;                                                                $\C{\color{red}// s.c, s.i, s.d}$
    1279 }
    1280 \end{cfa}
    1281 and the equivalence for object-style programming is:
    1282 \begin{cfa}
    1283 int mem( S & this ) `with( this )` {            $\C{// with clause}$
     1275void f( S & this ) `with ( this )` {            $\C{// with statement}$
    12841276        c; i; d;                                                                $\C{\color{red}// this.c, this.i, this.d}$
    12851277}
     
    12871279with the generality of opening multiple aggregate-parameters:
    12881280\begin{cfa}
    1289 int mem( S & s, T & t ) `with( s, t )` {        $\C{// multiple aggregate parameters}$
     1281int f( S & s, T & t ) `with ( s, t )` {         $\C{// multiple aggregate parameters}$
    12901282        c; i; d;                                                                $\C{\color{red}// s.c, s.i, s.d}$
    12911283        m; n;                                                                   $\C{\color{red}// t.m, t.n}$
     
    12931285\end{cfa}
    12941286
    1295 In detail, the @with@ clause/statement has the form:
     1287In detail, the @with@ statement has the form:
    12961288\begin{cfa}
    12971289$\emph{with-statement}$:
     
    13051297
    13061298All expressions in the expression list are open in ``parallel'' within the compound statement.
    1307 This semantic is different from Pascal, which nests the openings.
    1308 The difference between parallel and nesting occurs for fields with the same name but different type:
    1309 \begin{cfa}
    1310 struct S { int i; int j; double m; } s, w;
    1311 struct T { int i; int k; int m } t, w;
    1312 with( s, t ) {
    1313         j + k;                                                                  $\C{// unambiguous, s.j + t.m}$
     1299This semantic is different from Pascal, which nests the openings from left to right.
     1300The difference between parallel and nesting occurs for fields with the same name and type:
     1301\begin{cfa}
     1302struct S { int `i`; int j; double m; } s, w;
     1303struct T { int `i`; int k; int m; } t, w;
     1304with ( s, t ) {
     1305        j + k;                                                                  $\C{// unambiguous, s.j + t.k}$
    13141306        m = 5.0;                                                                $\C{// unambiguous, t.m = 5.0}$
    13151307        m = 1;                                                                  $\C{// unambiguous, s.m = 1}$
    1316         int a = s.i + m;                                                $\C{// unambiguous, a = s.i + t.i}$
    1317         int b = s.i + t.i;                                              $\C{// unambiguous, qualification}$
    1318         sout | (double)m | endl;                                $\C{// unambiguous, cast}$
    1319         i;                                                                              $\C{// ambiguous}$
    1320 }
    1321 \end{cfa}
    1322 \CFA's ability to overload variables means usages of field with the same names can be automatically disambiguated, eliminating most qualification.
     1308        int a = m;                                                              $\C{// unambiguous, a = s.i }$
     1309        double b = m;                                                   $\C{// unambiguous, b = t.m}$
     1310        int c = s.i + t.i;                                              $\C{// unambiguous, qualification}$
     1311        (double)m;                                                              $\C{// unambiguous, cast}$
     1312}
     1313\end{cfa}
     1314For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@ is ambiguous without qualification;
     1315for nested semantics, @t.i@ hides @s.i@, so @i@ implies @t.i@.
     1316\CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
    13231317Qualification or a cast is used to disambiguate.
    1324 A cast may be necessary to disambiguate between the overload variables in a @with@ expression:
    1325 \begin{cfa}
    1326 with( w ) { ... }                                                       $\C{// ambiguous, same name and no context}$
    1327 with( (S)w ) { ... }                                            $\C{// unambiguous}$
    1328 \end{cfa}
    1329 
     1318
     1319There is an interesting problem between parameters and the routine @with@, \eg:
     1320\begin{cfa}
     1321void ?{}( S & s, int i ) with ( s ) {           $\C{// constructor}$
     1322        `s.i = i;` j = 3; m = 5.5;
     1323}
     1324\end{cfa}
     1325Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the routine @with@.
     1326To solve this problem, parameters are treated like an initialized aggregate:
     1327\begin{cfa}
     1328struct Params {
     1329        S & s;
     1330        int i;
     1331} params;
     1332\end{cfa}
     1333and implicitly opened \emph{after} a routine open, to give them higher priority:
     1334\begin{cfa}
     1335void ?{}( S & s, int i ) with ( s ) `with( $\emph{\color{red}params}$ )` {
     1336        s.i = i; j = 3; m = 5.5;
     1337}
     1338\end{cfa}
     1339Finally, a cast may be used to disambiguate among overload variables in a @with@ expression:
     1340\begin{cfa}
     1341with ( w ) { ... }                                                      $\C{// ambiguous, same name and no context}$
     1342with ( (S)w ) { ... }                                           $\C{// unambiguous, cast}$
     1343\end{cfa}
     1344and @with@ expressions may be pointers and references (see Section~\ref{s:References}) to aggregates:
    13301345\begin{cfa}
    13311346struct S { int i, j; } sv;
    1332 with( sv ) {
     1347with ( sv ) {                                                           $\C{variable}$
    13331348        S & sr = sv;
    1334         with( sr ) {
     1349        with ( sr ) {                                                   $\C{reference}$
    13351350                S * sp = &sv;
    1336                 with( *sp ) {
     1351                with ( *sp ) {                                          $\C{pointer}$
    13371352                        i = 3; j = 4;                                   $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$
    13381353                }
     
    13431358\end{cfa}
    13441359
    1345 The statement form is used within a block:
    1346 \begin{cfa}
    1347 int foo() {
    1348         struct S1 { ... } s1;
    1349         struct S2 { ... } s2;
    1350         `with( s1 )` {                                                  $\C{// with statement}$
    1351                 // access fields of s1 without qualification
    1352                 `with( s2 )` {                                          $\C{// nesting}$
    1353                         // access fields of s1 and s2 without qualification
    1354                 }
    1355         }
    1356         `with( s1, s2 )` {
    1357                 // access unambiguous fields of s1 and s2 without qualification
    1358         }
    1359 }
    1360 \end{cfa}
    13611360
    13621361% \subsection{Exception Handling ???}
    13631362
     1363
    13641364\section{Declarations}
    13651365
    1366 It is important to the design team that \CFA subjectively ``feel like'' C to user programmers.
    1367 An important part of this subjective feel is maintaining C's procedural programming paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust.
    1368 Maintaining this procedural paradigm means that coding patterns that work in C will remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development.
    1369 Nonetheless, some features of object-oriented languages are undeniably convienient, and the \CFA design team has attempted to adapt them to a procedural paradigm so as to incorporate their benefits into \CFA; two of these features are resource management and name scoping.
     1366It is important that \CFA subjectively ``feel like'' C to user programmers.
     1367An important part of this subjective feel is maintaining C's procedural paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust.
     1368Maintaining this procedural paradigm means that C coding-patterns remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development.
     1369Nonetheless, some features of object-oriented languages are undeniably convienient but are independent of object-oriented programming;
     1370\CFA adapts these features to a procedural paradigm.
    13701371
    13711372
    13721373\subsection{Alternative Declaration Syntax}
    1373 
    1374 \newcommand{\R}[1]{\Textbf{#1}}
    1375 \newcommand{\B}[1]{{\Textbf[blue]{#1}}}
    1376 \newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}}
    13771374
    13781375C declaration syntax is notoriously confusing and error prone.
     
    14021399\CFA provides its own type, variable and routine declarations, using a different syntax.
    14031400The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
    1404 In the following example, \R{red} is the base type and \B{blue} is qualifiers.
    1405 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.
     1401The qualifiers have the same meaning but are ordered left to right to specify a variable's type.
    14061402\begin{cquote}
    14071403\lstDeleteShortInline@%
    1408 \lstset{moredelim=**[is][\color{blue}]{+}{+}}
    14091404\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    14101405\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    14111406\begin{cfa}
    1412 +[5] *+ `int` x1;
    1413 +* [5]+ `int` x2;
    1414 `[* [5] int]` f+( int p )+;
    1415 \end{cfa}
    1416 &
    1417 \begin{cfa}
    1418 `int` +*+ x1 +[5]+;
    1419 `int` +(*+x2+)[5]+;
    1420 `int (*`f+( int p )+`)[5]`;
     1407`[5] *` int x1;
     1408`* [5]` int x2;
     1409`[* [5] int]` f( int p );
     1410\end{cfa}
     1411&
     1412\begin{cfa}
     1413int `*` x1 `[5]`;
     1414int `(*`x2`)[5]`;
     1415`int (*`f( int p )`)[5]`;
    14211416\end{cfa}
    14221417\end{tabular}
     
    14591454\end{cquote}
    14601455which is prescribing a safety benefit.
     1456
     1457\begin{comment}
    14611458Other examples are:
    14621459\begin{cquote}
     
    14991496\lstMakeShortInline@%
    15001497\end{cquote}
    1501 
    1502 All type qualifiers, \eg @const@, @volatile@, etc., are used in the normal way with the new declarations and also appear left to right, \eg:
     1498\end{comment}
     1499
     1500All specifiers (@extern@, @static@, \etc) and qualifiers (@const@, @volatile@, \etc) are used in the normal way with the new declarations and also appear left to right, \eg:
    15031501\begin{cquote}
    15041502\lstDeleteShortInline@%
    1505 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
    1506 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{C}}      \\
    1507 \begin{cfa}
    1508 const * const int x;
    1509 const * [ 5 ] const int y;
    1510 \end{cfa}
    1511 &
    1512 \begin{cfa}
    1513 int const * const x;
    1514 const int (* const y)[ 5 ]
    1515 \end{cfa}
    1516 &
    1517 \begin{cfa}
    1518 // const pointer to const integer
    1519 // const pointer to array of 5 const integers
     1503\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}}
     1504\multicolumn{1}{c@{\hspace{1em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}} \\
     1505\begin{cfa}
     1506extern const * const int x;
     1507static const * [ 5 ] const int y;
     1508\end{cfa}
     1509&
     1510\begin{cfa}
     1511int extern const * const x;
     1512static const int (* const y)[ 5 ]
     1513\end{cfa}
     1514&
     1515\begin{cfa}
     1516// external const pointer to const int
     1517// internal const pointer to array of 5 const int
    15201518\end{cfa}
    15211519\end{tabular}
    15221520\lstMakeShortInline@%
    15231521\end{cquote}
    1524 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}
    1525 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:
    1526 \begin{cquote}
    1527 \lstDeleteShortInline@%
    1528 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
    1529 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{C}}      \\
    1530 \begin{cfa}
    1531 extern [ 5 ] int x;
    1532 static * const int y;
    1533 \end{cfa}
    1534 &
    1535 \begin{cfa}
    1536 int extern x[ 5 ];
    1537 const int static * y;
    1538 \end{cfa}
    1539 &
    1540 \begin{cfa}
    1541 // externally visible array of 5 integers
    1542 // internally visible pointer to constant int
    1543 \end{cfa}
    1544 \end{tabular}
    1545 \lstMakeShortInline@%
    1546 \end{cquote}
     1522All specifiers must appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
     1523The 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}}.
    15471524
    15481525The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@:
     
    15641541\end{cquote}
    15651542
    1566 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
    1567 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
    1568 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems.
    1569 
    15701543The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
    15711544as well, parameter names are optional, \eg:
    15721545\begin{cfa}
    15731546[ int x ] f ();                                                 $\C{// returning int with no parameters}$
    1574 [ * int ] g (int y);                                    $\C{// returning pointer to int with int parameter}$
     1547[ int x ] f (...);                                              $\C{// returning int with unknown parameters}$
     1548[ * int ] g ( int y );                                  $\C{// returning pointer to int with int parameter}$
    15751549[ ] h ( int, char );                                    $\C{// returning no result with int and char parameters}$
    15761550[ * int, int ] j ( int );                               $\C{// returning pointer to int and int, with int parameter}$
     
    15921566\lstMakeShortInline@%
    15931567\end{cquote}
    1594 \CFA allows the last routine in the list to define its body.
    1595 
    1596 Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
    1597 \begin{cfa}
    1598 extern [ int ] f ( int );
    1599 static [ int ] g ( int );
    1600 \end{cfa}
     1568where \CFA allows the last routine in the list to define its body.
    16011569
    16021570The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    16031571\begin{cfa}
    16041572* [ int x ] () fp;                                              $\C{// pointer to routine returning int with no parameters}$
    1605 * [ * int ] (int y) gp;                                 $\C{// pointer to routine returning pointer to int with int parameter}$
    1606 * [ ] (int,char) hp;                                    $\C{// pointer to routine returning no result with int and char parameters}$
    1607 * [ * int,int ] ( int ) jp;                             $\C{// pointer to routine returning pointer to int and int, with int parameter}$
    1608 \end{cfa}
    1609 While parameter names are optional, \emph{a routine name cannot be specified};
    1610 for example, the following is incorrect:
    1611 \begin{cfa}
    1612 * [ int x ] f () fp;                                    $\C{// routine name "f" is not allowed}$
    1613 \end{cfa}
     1573* [ * int ] ( int y ) gp;                               $\C{// pointer to routine returning pointer to int with int parameter}$
     1574* [ ] ( int, char ) hp;                                 $\C{// pointer to routine returning no result with int and char parameters}$
     1575* [ * int, int ] ( int ) jp;                    $\C{// pointer to routine returning pointer to int and int, with int parameter}$
     1576\end{cfa}
     1577Note, \emph{a routine name cannot be specified}:
     1578\begin{cfa}
     1579* [ int x ] f () fp;                                    $\C{// routine name "f" is disallowed}$
     1580\end{cfa}
     1581
     1582Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
     1583Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
     1584Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems.
    16141585
    16151586
    16161587\subsection{References}
     1588\label{s:References}
    16171589
    16181590All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type};
Note: See TracChangeset for help on using the changeset viewer.