Changeset 370f6ef for doc/papers/general/Paper.tex
- Timestamp:
- Feb 18, 2018, 9:33:18 AM (7 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Paper.tex
r2b95887 r370f6ef 90 90 \newcommand*{\etc}{% 91 91 \@ifnextchar{.}{\ETC}% 92 {\ETC \xspace}%92 {\ETC.\xspace}% 93 93 }% 94 \newcommand{\ETAL}{\abbrevFont{et} \hspace{2pt}\abbrevFont{al}}94 \newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}} 95 95 \newcommand*{\etal}{% 96 96 \@ifnextchar{.}{\protect\ETAL}% 97 {\ abbrevFont{\protect\ETAL}.\xspace}%97 {\protect\ETAL.\xspace}% 98 98 }% 99 99 \newcommand{\VIZ}{\abbrevFont{viz}} 100 100 \newcommand*{\viz}{% 101 101 \@ifnextchar{.}{\VIZ}% 102 {\ abbrevFont{\VIZ}.\xspace}%102 {\VIZ.\xspace}% 103 103 }% 104 104 \makeatother … … 120 120 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 121 121 __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}, 122 125 moredirectives={defined,include_next}% 123 } %126 } 124 127 125 128 \lstset{ … … 233 236 234 237 C 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; 239 Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C. 236 240 Code 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. 237 241 As an example: … … 254 258 The 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@. 255 259 Ergonomic 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 256 265 257 266 \subsection{\texorpdfstring{\LstKeywordStyle{forall} Functions}{forall Functions}} … … 290 299 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, 291 300 int (* compar)( const void *, const void * )); 301 292 302 int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 : 293 303 *(double *)t2 < *(double *)t1 ? 1 : 0; } 304 294 305 double key = 5.0, vals[10] = { /* 10 sorted float values */ }; 295 306 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); $\C{// search sorted array}$ … … 300 311 int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ } 301 312 return (T *)bsearch( &key, arr, size, sizeof(T), comp ); } 313 302 314 forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) { 303 315 T * result = bsearch( key, arr, size ); $\C{// call first version}$ 304 316 return result ? result - arr : size; } $\C{// pointer subtraction includes sizeof(T)}$ 317 305 318 double * val = bsearch( 5.0, vals, 10 ); $\C{// selection based on return type}$ 306 319 int posn = bsearch( 5.0, vals, 10 ); … … 311 324 \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@. 312 325 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}). 314 327 For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@: 315 328 \begin{lstlisting} … … 346 359 \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: 347 360 \begin{lstlisting} 348 trait summable( otype T ) {361 trait `summable`( otype T ) { 349 362 void ?{}( T *, zero_t ); $\C{// constructor from 0 literal}$ 350 363 T ?+?( T, T ); $\C{// assortment of additions}$ … … 352 365 T ++?( T * ); 353 366 T ?++( T * ); }; 367 354 368 forall( otype T `| summable( T )` ) T sum( T a[$\,$], size_t size ) { // use trait 355 369 `T` total = { `0` }; $\C{// instantiate T from 0 by calling its constructor}$ … … 425 439 forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; } 426 440 forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; } 441 427 442 pair( const char *, int ) p = { "magic", 42 }; 428 443 int magic = value( p ); … … 1150 1165 @case@ clauses are made disjoint by the @break@ statement. 1151 1166 While 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 newcontrol structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:1167 For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through: 1153 1168 \begin{cquote} 1154 1169 \lstDeleteShortInline@% … … 1157 1172 \begin{cfa} 1158 1173 `choose` ( day ) { 1159 case Mon~Thu: 1160 // program 1161 1162 case Fri: 1163 // program 1174 case Mon~Thu: // program 1175 1176 case Fri: // program 1164 1177 wallet += pay; 1165 1178 `fallthrough;` 1166 case Sat: 1167 // party 1179 case Sat: // party 1168 1180 wallet -= party; 1169 1181 1170 case Sun: 1171 // rest 1172 1173 default: 1174 // error 1182 case Sun: // rest 1183 1184 default: // error 1175 1185 } 1176 1186 \end{cfa} … … 1178 1188 \begin{cfa} 1179 1189 switch ( day ) { 1180 case Mon: case Tue: case Wed: case Thu: 1181 // program 1190 case Mon: case Tue: case Wed: case Thu: // program 1182 1191 `break;` 1183 case Fri: 1184 // program 1192 case Fri: // program 1185 1193 wallet += pay; 1186 1194 1187 case Sat: 1188 // party 1195 case Sat: // party 1189 1196 wallet -= party; 1190 1197 `break;` 1191 case Sun: 1192 // rest 1198 case Sun: // rest 1193 1199 `break;` 1194 default: 1195 // error 1200 default: // error 1196 1201 } 1197 1202 \end{cfa} … … 1228 1233 \label{s:WithClauseStatement} 1229 1234 1230 Grouping heterogen ous 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: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: 1231 1236 \begin{cfa} 1232 1237 struct S { $\C{// aggregate}$ … … 1243 1248 } 1244 1249 \end{cfa} 1250 which extends to multiple levels of qualification for nested aggregates. 1245 1251 A similar situation occurs in object-oriented programming, \eg \CC: 1246 1252 \begin{C++} … … 1249 1255 int i; 1250 1256 double d; 1251 int mem() { $\C{// implicit "this" parameter}$1257 int f() { $\C{// implicit "this" parameter}$ 1252 1258 `this->`c; `this->`i; `this->`d; $\C{// access containing fields}$ 1253 1259 } 1254 1260 } 1255 1261 \end{C++} 1256 Nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.1262 Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping. 1257 1263 However, for other aggregate parameters, qualification is necessary: 1258 1264 \begin{cfa} 1259 1265 struct T { double m, n; }; 1260 int C:: mem( T & t ) {$\C{// multiple aggregate parameters}$1266 int C::f( T & t ) { $\C{// multiple aggregate parameters}$ 1261 1267 c; i; d; $\C{\color{red}// this-\textgreater.c, this-\textgreater.i, this-\textgreater.d}$ 1262 1268 `t.`m; `t.`n; $\C{// must qualify}$ … … 1264 1270 \end{cfa} 1265 1271 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. 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. 1275 1273 Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block. 1276 1274 \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}$ 1275 void f( S & this ) `with ( this )` { $\C{// with statement}$ 1284 1276 c; i; d; $\C{\color{red}// this.c, this.i, this.d}$ 1285 1277 } … … 1287 1279 with the generality of opening multiple aggregate-parameters: 1288 1280 \begin{cfa} 1289 int mem( S & s, T & t ) `with( s, t )` {$\C{// multiple aggregate parameters}$1281 int f( S & s, T & t ) `with ( s, t )` { $\C{// multiple aggregate parameters}$ 1290 1282 c; i; d; $\C{\color{red}// s.c, s.i, s.d}$ 1291 1283 m; n; $\C{\color{red}// t.m, t.n}$ … … 1293 1285 \end{cfa} 1294 1286 1295 In detail, the @with@ clause/statement has the form:1287 In detail, the @with@ statement has the form: 1296 1288 \begin{cfa} 1297 1289 $\emph{with-statement}$: … … 1305 1297 1306 1298 All 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 differenttype: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}$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}$ 1314 1306 m = 5.0; $\C{// unambiguous, t.m = 5.0}$ 1315 1307 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} 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. 1323 1317 Qualification 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 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: 1330 1345 \begin{cfa} 1331 1346 struct S { int i, j; } sv; 1332 with ( sv ) {1347 with ( sv ) { $\C{variable}$ 1333 1348 S & sr = sv; 1334 with ( sr ) {1349 with ( sr ) { $\C{reference}$ 1335 1350 S * sp = &sv; 1336 with ( *sp ) {1351 with ( *sp ) { $\C{pointer}$ 1337 1352 i = 3; j = 4; $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$ 1338 1353 } … … 1343 1358 \end{cfa} 1344 1359 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 qualification1352 `with( s2 )` { $\C{// nesting}$1353 // access fields of s1 and s2 without qualification1354 }1355 }1356 `with( s1, s2 )` {1357 // access unambiguous fields of s1 and s2 without qualification1358 }1359 }1360 \end{cfa}1361 1360 1362 1361 % \subsection{Exception Handling ???} 1363 1362 1363 1364 1364 \section{Declarations} 1365 1365 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. 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. 1370 1371 1371 1372 1372 1373 \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}}}1377 1374 1378 1375 C declaration syntax is notoriously confusing and error prone. … … 1402 1399 \CFA provides its own type, variable and routine declarations, using a different syntax. 1403 1400 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type. 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. 1401 The qualifiers have the same meaning but are ordered left to right to specify a variable's type. 1406 1402 \begin{cquote} 1407 1403 \lstDeleteShortInline@% 1408 \lstset{moredelim=**[is][\color{blue}]{+}{+}}1409 1404 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}} 1410 1405 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1411 1406 \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} 1413 int `*` x1 `[5]`; 1414 int `(*`x2`)[5]`; 1415 `int (*`f( int p )`)[5]`; 1421 1416 \end{cfa} 1422 1417 \end{tabular} … … 1459 1454 \end{cquote} 1460 1455 which is prescribing a safety benefit. 1456 1457 \begin{comment} 1461 1458 Other examples are: 1462 1459 \begin{cquote} … … 1499 1496 \lstMakeShortInline@% 1500 1497 \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 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: 1503 1501 \begin{cquote} 1504 1502 \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 integer1519 // const pointer to array of 5 const integers1503 \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 1520 1518 \end{cfa} 1521 1519 \end{tabular} 1522 1520 \lstMakeShortInline@% 1523 1521 \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} 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}}. 1547 1524 1548 1525 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@: … … 1564 1541 \end{cquote} 1565 1542 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 1570 1543 The syntax of the new routine prototype declaration follows directly from the new routine definition syntax; 1571 1544 as well, parameter names are optional, \eg: 1572 1545 \begin{cfa} 1573 1546 [ 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}$ 1575 1549 [ ] h ( int, char ); $\C{// returning no result with int and char parameters}$ 1576 1550 [ * int, int ] j ( int ); $\C{// returning pointer to int and int, with int parameter}$ … … 1592 1566 \lstMakeShortInline@% 1593 1567 \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} 1568 where \CFA allows the last routine in the list to define its body. 1601 1569 1602 1570 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 1603 1571 \begin{cfa} 1604 1572 * [ 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} 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. 1614 1585 1615 1586 1616 1587 \subsection{References} 1588 \label{s:References} 1617 1589 1618 1590 All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type};
Note: See TracChangeset
for help on using the changeset viewer.