Changes in / [370f6ef:2b95887]


Ignore:
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    r370f6ef r2b95887  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Feb 17 21:58:43 2018
    14 %% Update Count     : 369
     13%% Last Modified On : Tue Feb 13 08:19:07 2018
     14%% Update Count     : 367
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    147147
    148148% Latin abbreviation
    149 \newcommand{\abbrevFont}{\textit}                       % set empty for no italics
     149\newcommand{\abbrevFont}{\textit}               % set empty for no italics
    150150\newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.}
    151151\newcommand*{\eg}{%
     
    163163\newcommand*{\etc}{%
    164164        \@ifnextchar{.}{\ETC}%
    165         {\ETC.\xspace}%
    166 }%
    167 \newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}}
     165        {\ETC\xspace}%
     166}%
     167\newcommand{\ETAL}{\abbrevFont{et}\hspace{2pt}\abbrevFont{al}}
    168168\newcommand*{\etal}{%
    169169        \@ifnextchar{.}{\protect\ETAL}%
    170                 {\protect\ETAL.\xspace}%
     170                {\abbrevFont{\protect\ETAL}.\xspace}%
    171171}%
    172172\newcommand{\VIZ}{\abbrevFont{viz}}
    173173\newcommand*{\viz}{%
    174174        \@ifnextchar{.}{\VIZ}%
    175                 {\VIZ.\xspace}%
     175                {\abbrevFont{\VIZ}.\xspace}%
    176176}%
    177177\makeatother
  • doc/papers/general/Paper.tex

    r370f6ef r2b95887  
    9090\newcommand*{\etc}{%
    9191        \@ifnextchar{.}{\ETC}%
    92         {\ETC.\xspace}%
     92        {\ETC\xspace}%
    9393}%
    94 \newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}}
     94\newcommand{\ETAL}{\abbrevFont{et}\hspace{2pt}\abbrevFont{al}}
    9595\newcommand*{\etal}{%
    9696        \@ifnextchar{.}{\protect\ETAL}%
    97                 {\protect\ETAL.\xspace}%
     97                {\abbrevFont{\protect\ETAL}.\xspace}%
    9898}%
    9999\newcommand{\VIZ}{\abbrevFont{viz}}
    100100\newcommand*{\viz}{%
    101101        \@ifnextchar{.}{\VIZ}%
    102                 {\VIZ.\xspace}%
     102                {\abbrevFont{\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},
    125122        moredirectives={defined,include_next}%
    126 }
     123}%
    127124
    128125\lstset{
     
    236233
    237234C 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.
    238 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable;
    239 Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C.
     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.
    240236Code 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.
    241237As an example:
     
    258254The 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@.
    259255Ergonomic 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 
    265256
    266257\subsection{\texorpdfstring{\LstKeywordStyle{forall} Functions}{forall Functions}}
     
    299290void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
    300291                                int (* compar)( const void *, const void * ));
    301 
    302292int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 :
    303293                                *(double *)t2 < *(double *)t1 ? 1 : 0; }
    304 
    305294double key = 5.0, vals[10] = { /* 10 sorted float values */ };
    306295double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      $\C{// search sorted array}$
     
    311300        int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ }
    312301        return (T *)bsearch( &key, arr, size, sizeof(T), comp ); }
    313 
    314302forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
    315303        T * result = bsearch( key, arr, size ); $\C{// call first version}$
    316304        return result ? result - arr : size; }  $\C{// pointer subtraction includes sizeof(T)}$
    317 
    318305double * val = bsearch( 5.0, vals, 10 );        $\C{// selection based on return type}$
    319306int posn = bsearch( 5.0, vals, 10 );
     
    324311\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@.
    325312
    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}).
     313\CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations.
    327314For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@:
    328315\begin{lstlisting}
     
    359346\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:
    360347\begin{lstlisting}
    361 trait `summable`( otype T ) {
     348trait summable( otype T ) {
    362349        void ?{}( T *, zero_t );                                $\C{// constructor from 0 literal}$
    363350        T ?+?( T, T );                                                  $\C{// assortment of additions}$
     
    365352        T ++?( T * );
    366353        T ?++( T * ); };
    367 
    368354forall( otype T `| summable( T )` ) T sum( T a[$\,$], size_t size ) {  // use trait
    369355        `T` total = { `0` };                                    $\C{// instantiate T from 0 by calling its constructor}$
     
    439425forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; }
    440426forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; }
    441 
    442427pair( const char *, int ) p = { "magic", 42 };
    443428int magic = value( p );
     
    11651150@case@ clauses are made disjoint by the @break@ statement.
    11661151While 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.
    1167 For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:
     1152\CFA provides a new control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:
    11681153\begin{cquote}
    11691154\lstDeleteShortInline@%
     
    11721157\begin{cfa}
    11731158`choose` ( day ) {
    1174   case Mon~Thu:  // program
    1175 
    1176   case Fri:  // program
     1159  case Mon~Thu:
     1160        // program
     1161
     1162  case Fri:
     1163        // program
    11771164        wallet += pay;
    11781165        `fallthrough;`
    1179   case Sat:  // party
     1166  case Sat:
     1167        // party
    11801168        wallet -= party;
    11811169
    1182   case Sun:  // rest
    1183 
    1184   default:  // error
     1170  case Sun:
     1171        // rest
     1172
     1173  default:
     1174        // error
    11851175}
    11861176\end{cfa}
     
    11881178\begin{cfa}
    11891179switch ( day ) {
    1190   case Mon: case Tue: case Wed: case Thu:  // program
     1180  case Mon: case Tue: case Wed: case Thu:
     1181        // program
    11911182        `break;`
    1192   case Fri:  // program
     1183  case Fri:
     1184        // program
    11931185        wallet += pay;
    11941186
    1195   case Sat:  // party
     1187  case Sat:
     1188        // party
    11961189        wallet -= party;
    11971190        `break;`
    1198   case Sun:  // rest
     1191  case Sun:
     1192        // rest
    11991193        `break;`
    1200   default:  // error
     1194  default:
     1195        // error
    12011196}
    12021197\end{cfa}
     
    12331228\label{s:WithClauseStatement}
    12341229
    1235 Grouping 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:
     1230Grouping 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:
    12361231\begin{cfa}
    12371232struct S {                                                                      $\C{// aggregate}$
     
    12481243}
    12491244\end{cfa}
    1250 which extends to multiple levels of qualification for nested aggregates.
    12511245A similar situation occurs in object-oriented programming, \eg \CC:
    12521246\begin{C++}
     
    12551249        int i;
    12561250        double d;
    1257         int f() {                                                               $\C{// implicit "this" parameter}$
     1251        int mem() {                                                             $\C{// implicit "this" parameter}$
    12581252                `this->`c; `this->`i; `this->`d;        $\C{// access containing fields}$
    12591253        }
    12601254}
    12611255\end{C++}
    1262 Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
     1256Nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
    12631257However, for other aggregate parameters, qualification is necessary:
    12641258\begin{cfa}
    12651259struct T { double m, n; };
    1266 int C::f( T & t ) {                                                     $\C{// multiple aggregate parameters}$
     1260int C::mem( T & t ) {                                           $\C{// multiple aggregate parameters}$
    12671261        c; i; d;                                                                $\C{\color{red}// this-\textgreater.c, this-\textgreater.i, this-\textgreater.d}$
    12681262        `t.`m; `t.`n;                                                   $\C{// must qualify}$
     
    12701264\end{cfa}
    12711265
    1272 To 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.
     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
     1274To 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.
    12731275Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block.
    12741276\begin{cfa}
    1275 void f( S & this ) `with ( this )` {            $\C{// with statement}$
     1277void 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}
     1281and the equivalence for object-style programming is:
     1282\begin{cfa}
     1283int mem( S & this ) `with( this )` {            $\C{// with clause}$
    12761284        c; i; d;                                                                $\C{\color{red}// this.c, this.i, this.d}$
    12771285}
     
    12791287with the generality of opening multiple aggregate-parameters:
    12801288\begin{cfa}
    1281 int f( S & s, T & t ) `with ( s, t )` {         $\C{// multiple aggregate parameters}$
     1289int mem( S & s, T & t ) `with( s, t )` {        $\C{// multiple aggregate parameters}$
    12821290        c; i; d;                                                                $\C{\color{red}// s.c, s.i, s.d}$
    12831291        m; n;                                                                   $\C{\color{red}// t.m, t.n}$
     
    12851293\end{cfa}
    12861294
    1287 In detail, the @with@ statement has the form:
     1295In detail, the @with@ clause/statement has the form:
    12881296\begin{cfa}
    12891297$\emph{with-statement}$:
     
    12971305
    12981306All expressions in the expression list are open in ``parallel'' within the compound statement.
    1299 This semantic is different from Pascal, which nests the openings from left to right.
    1300 The difference between parallel and nesting occurs for fields with the same name and type:
    1301 \begin{cfa}
    1302 struct S { int `i`; int j; double m; } s, w;
    1303 struct T { int `i`; int k; int m; } t, w;
    1304 with ( s, t ) {
    1305         j + k;                                                                  $\C{// unambiguous, s.j + t.k}$
     1307This semantic is different from Pascal, which nests the openings.
     1308The difference between parallel and nesting occurs for fields with the same name but different type:
     1309\begin{cfa}
     1310struct S { int i; int j; double m; } s, w;
     1311struct T { int i; int k; int m } t, w;
     1312with( s, t ) {
     1313        j + k;                                                                  $\C{// unambiguous, s.j + t.m}$
    13061314        m = 5.0;                                                                $\C{// unambiguous, t.m = 5.0}$
    13071315        m = 1;                                                                  $\C{// unambiguous, s.m = 1}$
    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}
    1314 For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@ is ambiguous without qualification;
    1315 for 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.
     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.
    13171323Qualification or a cast is used to disambiguate.
    1318 
    1319 There is an interesting problem between parameters and the routine @with@, \eg:
    1320 \begin{cfa}
    1321 void ?{}( S & s, int i ) with ( s ) {           $\C{// constructor}$
    1322         `s.i = i;` j = 3; m = 5.5;
    1323 }
    1324 \end{cfa}
    1325 Here, 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@.
    1326 To solve this problem, parameters are treated like an initialized aggregate:
    1327 \begin{cfa}
    1328 struct Params {
    1329         S & s;
    1330         int i;
    1331 } params;
    1332 \end{cfa}
    1333 and implicitly opened \emph{after} a routine open, to give them higher priority:
    1334 \begin{cfa}
    1335 void ?{}( S & s, int i ) with ( s ) `with( $\emph{\color{red}params}$ )` {
    1336         s.i = i; j = 3; m = 5.5;
    1337 }
    1338 \end{cfa}
    1339 Finally, a cast may be used to disambiguate among overload variables in a @with@ expression:
    1340 \begin{cfa}
    1341 with ( w ) { ... }                                                      $\C{// ambiguous, same name and no context}$
    1342 with ( (S)w ) { ... }                                           $\C{// unambiguous, cast}$
    1343 \end{cfa}
    1344 and @with@ expressions may be pointers and references (see Section~\ref{s:References}) to aggregates:
     1324A cast may be necessary to disambiguate between the overload variables in a @with@ expression:
     1325\begin{cfa}
     1326with( w ) { ... }                                                       $\C{// ambiguous, same name and no context}$
     1327with( (S)w ) { ... }                                            $\C{// unambiguous}$
     1328\end{cfa}
     1329
    13451330\begin{cfa}
    13461331struct S { int i, j; } sv;
    1347 with ( sv ) {                                                           $\C{variable}$
     1332with( sv ) {
    13481333        S & sr = sv;
    1349         with ( sr ) {                                                   $\C{reference}$
     1334        with( sr ) {
    13501335                S * sp = &sv;
    1351                 with ( *sp ) {                                          $\C{pointer}$
     1336                with( *sp ) {
    13521337                        i = 3; j = 4;                                   $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$
    13531338                }
     
    13581343\end{cfa}
    13591344
     1345The statement form is used within a block:
     1346\begin{cfa}
     1347int 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}
    13601361
    13611362% \subsection{Exception Handling ???}
    13621363
    1363 
    13641364\section{Declarations}
    13651365
    1366 It is important that \CFA subjectively ``feel like'' C to user programmers.
    1367 An 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.
    1368 Maintaining 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.
    1369 Nonetheless, 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.
     1366It is important to the design team that \CFA subjectively ``feel like'' C to user programmers.
     1367An 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.
     1368Maintaining 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.
     1369Nonetheless, 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.
    13711370
    13721371
    13731372\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}}}
    13741377
    13751378C declaration syntax is notoriously confusing and error prone.
     
    13991402\CFA provides its own type, variable and routine declarations, using a different syntax.
    14001403The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type.
    1401 The qualifiers have the same meaning but are ordered left to right to specify a variable's type.
     1404In the following example, \R{red} is the base type and \B{blue} is qualifiers.
     1405The \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.
    14021406\begin{cquote}
    14031407\lstDeleteShortInline@%
     1408\lstset{moredelim=**[is][\color{blue}]{+}{+}}
    14041409\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    14051410\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    14061411\begin{cfa}
    1407 `[5] *` int x1;
    1408 `* [5]` int x2;
    1409 `[* [5] int]` f( int p );
    1410 \end{cfa}
    1411 &
    1412 \begin{cfa}
    1413 int `*` x1 `[5]`;
    1414 int `(*`x2`)[5]`;
    1415 `int (*`f( int p )`)[5]`;
     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]`;
    14161421\end{cfa}
    14171422\end{tabular}
     
    14541459\end{cquote}
    14551460which is prescribing a safety benefit.
    1456 
    1457 \begin{comment}
    14581461Other examples are:
    14591462\begin{cquote}
     
    14961499\lstMakeShortInline@%
    14971500\end{cquote}
    1498 \end{comment}
    1499 
    1500 All 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:
     1501
     1502All type qualifiers, \eg @const@, @volatile@, etc., are used in the normal way with the new declarations and also appear left to right, \eg:
    15011503\begin{cquote}
    15021504\lstDeleteShortInline@%
    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}
    1506 extern const * const int x;
    1507 static const * [ 5 ] const int y;
    1508 \end{cfa}
    1509 &
    1510 \begin{cfa}
    1511 int extern const * const x;
    1512 static 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
     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}
     1508const * const int x;
     1509const * [ 5 ] const int y;
     1510\end{cfa}
     1511&
     1512\begin{cfa}
     1513int const * const x;
     1514const 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
    15181520\end{cfa}
    15191521\end{tabular}
    15201522\lstMakeShortInline@%
    15211523\end{cquote}
    1522 All specifiers must appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
    1523 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}}.
     1524All 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}
     1525The 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}
     1531extern [ 5 ] int x;
     1532static * const int y;
     1533\end{cfa}
     1534&
     1535\begin{cfa}
     1536int extern x[ 5 ];
     1537const 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}
    15241547
    15251548The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@:
     
    15411564\end{cquote}
    15421565
     1566Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
     1567Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
     1568Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems.
     1569
    15431570The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
    15441571as well, parameter names are optional, \eg:
    15451572\begin{cfa}
    15461573[ int x ] f ();                                                 $\C{// returning int with no parameters}$
    1547 [ int x ] f (...);                                              $\C{// returning int with unknown parameters}$
    1548 [ * int ] g ( int y );                                  $\C{// returning pointer to int with int parameter}$
     1574[ * int ] g (int y);                                    $\C{// returning pointer to int with int parameter}$
    15491575[ ] h ( int, char );                                    $\C{// returning no result with int and char parameters}$
    15501576[ * int, int ] j ( int );                               $\C{// returning pointer to int and int, with int parameter}$
     
    15661592\lstMakeShortInline@%
    15671593\end{cquote}
    1568 where \CFA allows the last routine in the list to define its body.
     1594\CFA allows the last routine in the list to define its body.
     1595
     1596Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
     1597\begin{cfa}
     1598extern [ int ] f ( int );
     1599static [ int ] g ( int );
     1600\end{cfa}
    15691601
    15701602The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    15711603\begin{cfa}
    15721604* [ int x ] () fp;                                              $\C{// pointer to routine returning int with no parameters}$
    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}
    1577 Note, \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 
    1582 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration.
    1583 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.
    1584 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems.
     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}
     1609While parameter names are optional, \emph{a routine name cannot be specified};
     1610for example, the following is incorrect:
     1611\begin{cfa}
     1612* [ int x ] f () fp;                                    $\C{// routine name "f" is not allowed}$
     1613\end{cfa}
    15851614
    15861615
    15871616\subsection{References}
    1588 \label{s:References}
    15891617
    15901618All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type};
  • src/ResolvExpr/AlternativeFinder.cc

    r370f6ef r2b95887  
    1010// Created On       : Sat May 16 23:52:08 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 17 11:19:39 2018
    13 // Update Count     : 33
     12// Last Modified On : Mon Aug 28 13:47:24 2017
     13// Update Count     : 32
    1414//
    1515
     
    255255                                stream << "Cannot choose between " << winners.size() << " alternatives for expression\n";
    256256                                expr->print( stream );
    257                                 stream << " Alternatives are:\n";
     257                                stream << "Alternatives are:\n";
    258258                                printAlts( winners, stream, 1 );
    259259                                throw SemanticError( expr->location, stream.str() );
  • src/ResolvExpr/Resolver.cc

    r370f6ef r2b95887  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 17 11:19:40 2018
    13 // Update Count     : 213
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tus Aug  8 16:06:00 2017
     13// Update Count     : 212
    1414//
    1515
     
    179179                                stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n";
    180180                                untyped->print( stream );
    181                                 stream << " Alternatives are:\n";
     181                                stream << "Alternatives are:\n";
    182182                                printAlts( winners, stream, 1 );
    183183                                throw SemanticError( untyped->location, stream.str() );
  • src/tests/sum.c

    r370f6ef r2b95887  
    1111// Created On       : Wed May 27 17:56:53 2015
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sat Feb 17 11:49:17 2018
    14 // Update Count     : 273
     13// Last Modified On : Fri Jan 26 11:31:02 2018
     14// Update Count     : 271
    1515//
    1616
     
    8484        struct S { int i, j; };
    8585        void ?{}( S & s ) { s.[i, j] = 0; }
    86         void ?{}( S & s, int i ) { s.[i, j] = [i, 0]; }
    87         void ?{}( S & s, int i, int j ) { s.[i, j] = [i, j]; }
    88         void ?{}( S & s, zero_t ) { s.[i, j] = 0; }
    89         void ?{}( S & s, one_t ) { s.[i, j] = 1; }
     86        void ?{}( S & s, int i, int j ) { s.[i,j] = [i, j]; }
     87        void ?{}( S & s, zero_t ) { s.[i,j] = 0; }
     88        void ?{}( S & s, one_t ) { s.[i,j] = 1; }
    9089        S ?+?( S t1, S t2 ) { return (S){ t1.i + t2.i, t1.j + t2.j }; }
    9190        S ?+=?( S & t1, S t2 ) { t1 = t1 + t2; return t1; }
Note: See TracChangeset for help on using the changeset viewer.