Changes in doc/papers/general/Paper.tex [d52a55b:3d60c08]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Paper.tex
rd52a55b r3d60c08 59 59 %\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}} 60 60 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 61 62 \renewcommand*{\thefootnote}{\Alph{footnote}} % hack because fnsymbol does not work 63 %\renewcommand*{\thefootnote}{\fnsymbol{footnote}} 61 64 62 65 \makeatletter … … 174 177 \lstMakeShortInline@% 175 178 179 \let\OLDthebibliography\thebibliography 180 \renewcommand\thebibliography[1]{ 181 \OLDthebibliography{#1} 182 \setlength{\parskip}{0pt} 183 \setlength{\itemsep}{4pt plus 0.3ex} 184 } 176 185 177 186 \title{\texorpdfstring{\protect\CFA : Adding Modern Programming Language Features to C}{Cforall : Adding Modern Programming Language Features to C}} … … 191 200 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects. 192 201 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 193 Nevertheless, C, first standardized over thirty years ago, lacks many features that make programming in more modern languages safer and more productive. 194 The goal of the \CFA project is to create an extension of C that provides modern safety and productivity features while still ensuring strong backwards compatibility with C and its programmers. 202 Nevertheless, C, first standardized almost forty years ago, lacks many features that make programming in more modern languages safer and more productive. 203 204 The goal of the \CFA project (pronounced ``C-for-all'') is to create an extension of C that provides modern safety and productivity features while still ensuring strong backwards compatibility with C and its programmers. 195 205 Prior projects have attempted similar goals but failed to honour C programming-style; for instance, adding object-oriented or functional programming with garbage collection is a non-starter for many C developers. 196 206 Specifically, \CFA is designed to have an orthogonal feature-set based closely on the C programming paradigm, so that \CFA features can be added \emph{incrementally} to existing C code-bases, and C programmers can learn \CFA extensions on an as-needed basis, preserving investment in existing code and programmers. … … 226 236 Love it or hate it, C is extremely popular, highly used, and one of the few systems languages. 227 237 In many cases, \CC is often used solely as a better C. 228 Nevertheless, C, first standardized over thirty years ago, lacks many features that make programming in more modern languages safer and more productive.238 Nevertheless, C, first standardized almost forty years ago~\cite{ANSI89:C}, lacks many features that make programming in more modern languages safer and more productive. 229 239 230 240 \CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language-features to C, while maintaining both source and runtime compatibility with C and a familiar programming model for programmers. … … 239 249 All languages features discussed in this paper are working, except some advanced exception-handling features. 240 250 Not discussed in this paper are the integrated concurrency-constructs and user-level threading-library~\cite{Delisle18}. 241 \CFA is an \emph{open-source} project implemented as a nsource-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3).251 \CFA is an \emph{open-source} project implemented as a source-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3). 242 252 Ultimately, a compiler is necessary for advanced features and optimal performance. 243 253 % @plg2[9]% cd cfa-cc/src; cloc ArgTweak CodeGen CodeTools Common Concurrency ControlStruct Designators GenPoly InitTweak MakeLibCfa.cc MakeLibCfa.h Parser ResolvExpr SymTab SynTree Tuples driver prelude main.cc … … 292 302 The \CFA tests are 290+ files and 27,000+ lines of code. 293 303 The tests illustrate syntactic and semantic features in \CFA, plus a growing number of runtime benchmarks. 294 The tests check for correctness and are used for daily regression testing of commits (3800+).304 The tests check for correctness and are used for daily regression testing of 3800+ commits. 295 305 296 306 Finally, it is impossible to describe a programming language without usages before definitions. … … 313 323 There are only two hard things in Computer Science: cache invalidation and \emph{naming things} -- Phil Karlton 314 324 \end{quote} 315 \vspace{- 10pt}325 \vspace{-9pt} 316 326 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. 317 327 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable; … … 324 334 int max( int a, int b ) { return a < b ? b : a; } $\C{// (3)}$ 325 335 double max( double a, double b ) { return a < b ? b : a; } $\C{// (4)}\CRT$ 326 max( 7, -max ); $\C [2.75in]{// uses (3) and (1), by matching int from constant 7}$336 max( 7, -max ); $\C{// uses (3) and (1), by matching int from constant 7}$ 327 337 max( max, 3.14 ); $\C{// uses (4) and (2), by matching double from constant 3.14}$ 328 max( max, -max ); $\C{// ERROR :ambiguous}$329 int m = max( max, -max ); $\C{// uses (3) and (1) twice, by matching return type} \CRT$338 max( max, -max ); $\C{// ERROR, ambiguous}$ 339 int m = max( max, -max ); $\C{// uses (3) and (1) twice, by matching return type}$ 330 340 \end{cfa} 331 341 … … 336 346 As is shown later, there are a number of situations where \CFA takes advantage of available type information to disambiguate, where other programming languages generate ambiguities. 337 347 338 \Celeven added @_Generic@ expressions , which is used in preprocessor macros to provide a form ofad-hoc polymorphism;348 \Celeven added @_Generic@ expressions~\cite[\S~6.5.1.1]{C11}, which is used with preprocessor macros to provide ad-hoc polymorphism; 339 349 however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading. 340 350 The macro wrapping the generic expression imposes some limitations; 341 351 \eg, it cannot implement the example above, because the variables @max@ are ambiguous with the functions @max@. 342 352 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 dispatch functions, which must all have distinct names. 343 For backwards compatibility, \CFA supports @_Generic@ expressions, but it is an unnecessary mechanism. \TODO{actually implement that}353 \CFA supports @_Generic@ expressions for backwards compatibility, but it is an unnecessary mechanism. \TODO{actually implement that} 344 354 345 355 % http://fanf.livejournal.com/144696.html … … 369 379 \begin{cfa} 370 380 forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x `+` x; } $\C{// ? denotes operands}$ 371 int val = twice( twice( 3.7 ) ); 381 int val = twice( twice( 3.7 ) ); $\C{// val == 14}$ 372 382 \end{cfa} 373 383 which works for any type @T@ with a matching addition operator. 374 384 The polymorphism is achieved by creating a wrapper function for calling @+@ with @T@ bound to @double@, then passing this function to the first call of @twice@. 375 385 There is now the option of using the same @twice@ and converting the result to @int@ on assignment, or creating another @twice@ with type parameter @T@ bound to @int@ because \CFA uses the return type~\cite{Cormack81,Baker82,Ada} in its type analysis. 376 The first approach has a late conversion from @double@ to @int@ on the final assignment, while the second has an ea gerconversion to @int@.386 The first approach has a late conversion from @double@ to @int@ on the final assignment, while the second has an early conversion to @int@. 377 387 \CFA minimizes the number of conversions and their potential to lose information, so it selects the first approach, which corresponds with C-programmer intuition. 378 388 … … 420 430 \begin{cfa} 421 431 forall( otype T | { int ?<?( T, T ); } ) void qsort( const T * arr, size_t size ) { /* use C qsort */ } 422 {432 int main() { 423 433 int ?<?( double x, double y ) { return x `>` y; } $\C{// locally override behaviour}$ 424 qsort( vals, size );$\C{// descending sort}$434 qsort( vals, 10 ); $\C{// descending sort}$ 425 435 } 426 436 \end{cfa} … … 428 438 Hence, programmers can easily form local environments, adding and modifying appropriate functions, to maximize reuse of other existing functions and types. 429 439 430 To reduc ingduplication, it is possible to distribute a group of @forall@ (and storage-class qualifiers) over functions/types, so each block declaration is prefixed by the group (see example in Appendix~\ref{s:CforallStack}).440 To reduce duplication, it is possible to distribute a group of @forall@ (and storage-class qualifiers) over functions/types, so each block declaration is prefixed by the group (see example in Appendix~\ref{s:CforallStack}). 431 441 \begin{cfa} 432 442 forall( otype `T` ) { $\C{// distribution block, add forall qualifier to declarations}$ … … 470 480 \end{cquote} 471 481 472 In fact, the set of @summable@ trait operators is incomplete, as it is missing assignment for type @T@, but @otype@ is syntactic sugar for the following implicit trait: 482 Note, the @sumable@ trait does not include a copy constructor needed for the right side of @?+=?@ and return; 483 it is provided by @otype@, which is syntactic sugar for the following trait: 473 484 \begin{cfa} 474 485 trait otype( dtype T | sized(T) ) { // sized is a pseudo-trait for types with known size and alignment … … 488 499 Instead, each polymorphic function (or generic type) defines the structural type needed for its execution (polymorphic type-key), and this key is fulfilled at each call site from the lexical environment, which is similar to Go~\cite{Go} interfaces. 489 500 Hence, new lexical scopes and nested functions are used extensively to create local subtypes, as in the @qsort@ example, without having to manage a nominal-inheritance hierarchy. 490 (Nominal inheritance can be approximated with traits using marker variables or functions, as is done in Go.)501 % (Nominal inheritance can be approximated with traits using marker variables or functions, as is done in Go.) 491 502 492 503 % Nominal inheritance can be simulated with traits using marker variables or functions: … … 515 526 516 527 517 \vspace*{-2pt}518 528 \section{Generic Types} 519 529 … … 534 544 \begin{cquote} 535 545 \lstDeleteShortInline@% 536 \begin{tabular}{@{}l|@{\hspace{ 2\parindentlnth}}l@{}}537 \begin{cfa} 538 forall( otype R, otype S )struct pair {546 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 547 \begin{cfa} 548 `forall( otype R, otype S )` struct pair { 539 549 R first; S second; 540 550 }; … … 561 571 Concrete types have a fixed memory layout regardless of type parameters, while dynamic types vary in memory layout depending on their type parameters. 562 572 A \newterm{dtype-static} type has polymorphic parameters but is still concrete. 563 Polymorphic pointers are an example of dtype-static types, \eg @forall(dtype T) T *@ is a polymorphic type, but for any @T@, @T *@ is a fixed-sized pointer, and therefore, can be represented by a @void *@ in code generation. 573 Polymorphic pointers are an example of dtype-static types; 574 given some type variable @T@, @T@ is a polymorphic type, as is @T *@, but @T *@ has a fixed size and can therefore be represented by @void *@ in code generation. 564 575 565 576 \CFA generic types also allow checked argument-constraints. … … 578 589 \begin{cfa} 579 590 struct _pair_conc0 { 580 const char * first; 581 int second; 591 const char * first; int second; 582 592 }; 583 593 \end{cfa} … … 587 597 \begin{cfa} 588 598 struct _pair_conc1 { 589 void * first; 590 void * second; 599 void * first, * second; 591 600 }; 592 601 \end{cfa} … … 645 654 \begin{cquote} 646 655 \lstDeleteShortInline@% 647 \begin{tabular}{@{}l @{\hspace{2\parindentlnth}}l@{}}656 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 648 657 \begin{cfa} 649 658 forall( dtype Unit ) struct scalar { unsigned long value; }; … … 661 670 half_marathon; 662 671 scalar(litres) two_pools = pool + pool; 663 `marathon + pool;` // compilation ERROR672 `marathon + pool;` // ERROR, mismatched types 664 673 \end{cfa} 665 674 \end{tabular} … … 947 956 } 948 957 \end{cfa} 949 One more step permits the summation of any sum mable type with all arguments of the same type:950 \begin{cfa} 951 trait sum mable( otype T ) {958 One more step permits the summation of any sumable type with all arguments of the same type: 959 \begin{cfa} 960 trait sumable( otype T ) { 952 961 T ?+?( T, T ); 953 962 }; 954 forall( otype R | sum mable( R ) ) R sum( R x, R y ) {963 forall( otype R | sumable( R ) ) R sum( R x, R y ) { 955 964 return x + y; 956 965 } 957 forall( otype R, ttype Params | sum mable(R) | { R sum(R, Params); } ) R sum(R x, R y, Params rest) {966 forall( otype R, ttype Params | sumable(R) | { R sum(R, Params); } ) R sum(R x, R y, Params rest) { 958 967 return sum( x + y, rest ); 959 968 } … … 1006 1015 \begin{cfa} 1007 1016 forall( dtype T0, dtype T1 | sized(T0) | sized(T1) ) struct _tuple2 { 1008 T0 field_0; $\C{// generated before the first 2-tuple}$ 1009 T1 field_1; 1017 T0 field_0; T1 field_1; $\C{// generated before the first 2-tuple}$ 1010 1018 }; 1011 1019 _tuple2(int, int) f() { 1012 1020 _tuple2(double, double) x; 1013 1021 forall( dtype T0, dtype T1, dtype T2 | sized(T0) | sized(T1) | sized(T2) ) struct _tuple3 { 1014 T0 field_0; $\C{// generated before the first 3-tuple}$ 1015 T1 field_1; 1016 T2 field_2; 1022 T0 field_0; T1 field_1; T2 field_2; $\C{// generated before the first 3-tuple}$ 1017 1023 }; 1018 1024 _tuple3(int, double, int) y; 1019 1025 } 1020 1026 \end{cfa} 1021 {\sloppy 1022 Tuple expressions are then simply converted directly into compound literals, \eg @[5, 'x', 1.24]@ becomes @(_tuple3(int, char, double)){ 5, 'x', 1.24 }@. 1023 \par}% 1027 Tuple expressions are then converted directly into compound literals, \eg @[5, 'x', 1.24]@ becomes @(_tuple3(int, char,@ @double)){ 5, 'x', 1.24 }@. 1024 1028 1025 1029 \begin{comment} … … 1106 1110 \lstDeleteShortInline@% 1107 1111 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 1108 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1112 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1109 1113 \begin{cfa} 1110 1114 case 2, 10, 34, 42: … … 1121 1125 \lstDeleteShortInline@% 1122 1126 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 1123 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1127 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1124 1128 \begin{cfa} 1125 1129 case 2~42: … … 1174 1178 \centering 1175 1179 \lstDeleteShortInline@% 1176 \begin{tabular}{@{}l @{\hspace{2\parindentlnth}}l@{}}1177 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1180 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 1181 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1178 1182 \begin{cfa} 1179 1183 `choose` ( day ) { 1180 1184 case Mon~Thu: // program 1181 1185 1182 case Fri: // program1186 case Fri: // program 1183 1187 wallet += pay; 1184 1188 `fallthrough;` 1185 case Sat: // party1189 case Sat: // party 1186 1190 wallet -= party; 1187 1191 1188 1192 case Sun: // rest 1189 1193 1190 default: //error1194 default: // print error 1191 1195 } 1192 1196 \end{cfa} … … 1196 1200 case Mon: case Tue: case Wed: case Thu: // program 1197 1201 `break;` 1198 case Fri: // program1202 case Fri: // program 1199 1203 wallet += pay; 1200 1204 1201 case Sat: // party1205 case Sat: // party 1202 1206 wallet -= party; 1203 1207 `break;` 1204 1208 case Sun: // rest 1205 1209 `break;` 1206 default: //error1210 default: // print error 1207 1211 } 1208 1212 \end{cfa} … … 1220 1224 \centering 1221 1225 \lstDeleteShortInline@% 1222 \begin{tabular}{@{}l @{\hspace{2\parindentlnth}}l@{}}1223 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{non-terminator}} & \multicolumn{1}{c}{\textbf{target label}} \\1226 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 1227 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{non-terminator}} & \multicolumn{1}{c@{}}{\textbf{target label}} \\ 1224 1228 \begin{cfa} 1225 1229 choose ( ... ) { … … 1264 1268 \begin{figure} 1265 1269 \lstDeleteShortInline@% 1266 \begin{tabular}{@{\hspace{\parindentlnth}}l @{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}1267 \multicolumn{1}{@{\hspace{\parindentlnth}}c @{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c}{\textbf{C}} \\1270 \begin{tabular}{@{\hspace{\parindentlnth}}l|@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}} 1271 \multicolumn{1}{@{\hspace{\parindentlnth}}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{C}} \\ 1268 1272 \begin{cfa} 1269 1273 `LC:` { … … 1349 1353 \subsection{Exception Handling} 1350 1354 1351 The following framework for \CFA exception 1355 The following framework for \CFA exception-handling is in place, excluding some runtime type-information and virtual functions. 1352 1356 \CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling})~\cite{Buhr92b,Buhr00a}. 1353 1357 Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler. … … 1360 1364 \begin{cquote} 1361 1365 \lstDeleteShortInline@% 1362 \begin{tabular}{@{}l @{\hspace{2\parindentlnth}}l@{}}1363 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{Resumption}} & \multicolumn{1}{c}{\textbf{Termination}} \\1366 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 1367 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{Resumption}} & \multicolumn{1}{c@{}}{\textbf{Termination}} \\ 1364 1368 \begin{cfa} 1365 1369 `exception R { int fix; };` … … 1477 1481 If an exception is raised and caught, the handler is run before the finally clause. 1478 1482 Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated. 1479 Mimicking the @finally@ clause with mechanisms like RAII is non-trivial lywhen there are multiple types and local accesses.1483 Mimicking the @finally@ clause with mechanisms like RAII is non-trivial when there are multiple types and local accesses. 1480 1484 1481 1485 … … 1530 1534 with ( s, t ) { 1531 1535 j + k; $\C{// unambiguous, s.j + t.k}$ 1532 m = 5.0; $\C{// unambiguous, t.m = 5.0}$1533 m = 1; $\C{// unambiguous, s.m = 1}$1534 int a = m; $\C{// unambiguous, a = s.i}$1535 double b = m; $\C{// unambiguous, b = t.m}$1536 m = 5.0; $\C{// unambiguous, s.m = 5.0}$ 1537 m = 1; $\C{// unambiguous, t.m = 1}$ 1538 int a = m; $\C{// unambiguous, a = t.m }$ 1539 double b = m; $\C{// unambiguous, b = s.m}$ 1536 1540 int c = s.i + t.i; $\C{// unambiguous, qualification}$ 1537 (double)m; $\C{// unambiguous, cast }$1541 (double)m; $\C{// unambiguous, cast s.m}$ 1538 1542 } 1539 1543 \end{cfa} … … 1559 1563 and implicitly opened \emph{after} a function-body open, to give them higher priority: 1560 1564 \begin{cfa} 1561 void ?{}( S & s, int `i` ) with ( s ) ` with( $\emph{\color{red}params}$ )` {1565 void ?{}( S & s, int `i` ) with ( s ) `{` `with( $\emph{\color{red}params}$ )` { 1562 1566 s.i = `i`; j = 3; m = 5.5; 1563 } 1567 } `}` 1564 1568 \end{cfa} 1565 1569 Finally, a cast may be used to disambiguate among overload variables in a @with@ expression: … … 1629 1633 \lstDeleteShortInline@% 1630 1634 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{\hspace{2\parindentlnth}}l@{}} 1631 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1635 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1632 1636 \begin{cfa} 1633 1637 `[5] *` int x1; … … 1657 1661 \lstDeleteShortInline@% 1658 1662 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 1659 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1663 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1660 1664 \begin{cfa} 1661 1665 `*` int x, y; 1662 int y;1663 \end{cfa} 1664 & 1665 \begin{cfa} 1666 int `*`x, `*`y ;1666 int z; 1667 \end{cfa} 1668 & 1669 \begin{cfa} 1670 int `*`x, `*`y, z; 1667 1671 1668 1672 \end{cfa} … … 1670 1674 \lstMakeShortInline@% 1671 1675 \end{cquote} 1672 The downside of the \CFA semantics is the need to separate regular and pointer declarations. 1676 % The downside of the \CFA semantics is the need to separate regular and pointer declarations. 1677 The separation of regular and pointer declarations by \CFA declarations enforces greater clarity with only slightly more syntax. 1673 1678 1674 1679 \begin{comment} … … 1677 1682 \lstDeleteShortInline@% 1678 1683 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{\hspace{2\parindentlnth}}l@{}} 1679 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{C}} \\1684 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{C}} \\ 1680 1685 \begin{cfa} 1681 1686 [ 5 ] int z; … … 1719 1724 \lstDeleteShortInline@% 1720 1725 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{\hspace{2\parindentlnth}}l@{}} 1721 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{C}} \\1726 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{C}} \\ 1722 1727 \begin{cfa} 1723 1728 extern const * const int x; … … 1744 1749 \lstDeleteShortInline@% 1745 1750 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 1746 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1751 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1747 1752 \begin{cfa} 1748 1753 y = (* int)x; … … 1772 1777 \lstDeleteShortInline@% 1773 1778 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 1774 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1779 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 1775 1780 \begin{cfa} 1776 1781 [double] foo(), foo( int ), foo( double ) {...} … … 1790 1795 * [ * int ] ( int y ) gp; $\C{// pointer to function returning pointer to int with int parameter}$ 1791 1796 * [ ] ( int, char ) hp; $\C{// pointer to function returning no result with int and char parameters}$ 1792 * [ * int, int ] ( int ) jp; $\C{// pointer to function returning pointer to int and int with int parameter}$ 1793 \end{cfa} 1794 Note, a function name cannot be specified: 1795 \begin{cfa} 1796 * [ int x ] f () fp; $\C{// function name "f" is disallowed}\CRT$ 1797 \end{cfa} 1797 * [ * int, int ] ( int ) jp; $\C{// pointer to function returning pointer to int and int with int parameter}\CRT$ 1798 \end{cfa} 1799 Note, the name of the function pointer is specified last, as for other variable declarations. 1798 1800 1799 1801 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. … … 1852 1854 This provides a much more orthogonal design for library implementors, obviating the need for workarounds such as @std::reference_wrapper@. 1853 1855 Secondly, \CFA references are rebindable, whereas \CC references have a fixed address. 1854 \newsavebox{\LstBox}1855 \begin{lrbox}{\LstBox}1856 \lstset{basicstyle=\footnotesize\linespread{0.9}\sf}1857 \begin{cfa}1858 int & r = *new( int );1859 ... $\C{// non-null reference}$1860 delete &r; $\C{// unmanaged (programmer) memory-management}$1861 r += 1; $\C{// undefined reference}$1862 \end{cfa}1863 \end{lrbox}1864 1856 Rebinding allows \CFA references to be default-initialized (\eg to a null pointer\footnote{ 1865 While effort has been made into non-null reference checking in \CC and Java, the exercise seems moot for any non-managed languages (C/\CC), given that it only handles one of many different error situations: 1866 \begin{cquote} 1867 \usebox{\LstBox} 1868 \end{cquote} 1869 }% 1870 ) and point to different addresses throughout their lifetime, like pointers. 1857 While effort has been made into non-null reference checking in \CC and Java, the exercise seems moot for any non-managed languages (C/\CC), given that it only handles one of many different error situations, \eg using a pointer after its storage is deleted.}) and point to different addresses throughout their lifetime, like pointers. 1871 1858 Rebinding is accomplished by extending the existing syntax and semantics of the address-of operator in C. 1872 1859 … … 1880 1867 \begin{itemize} 1881 1868 \item 1882 if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) th an @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols).1869 if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) then @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols). 1883 1870 1884 1871 \item … … 1914 1901 \end{cfa} 1915 1902 This allows complex values to be succinctly and efficiently passed to functions, without the syntactic overhead of explicit definition of a temporary variable or the runtime cost of pass-by-value. 1916 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \newterm{const hell} problem, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers.1903 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \newterm{const poisoning} problem~\cite{Taylor10}, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers. 1917 1904 1918 1905 … … 1928 1915 \begin{tabular}{@{}l@{\hspace{3em}}l|l@{}} 1929 1916 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}} & \multicolumn{1}{c|}{\textbf{C Implicit Hoisting}} & \multicolumn{1}{c}{\textbf{\CFA}} \\ 1930 \hline1931 1917 \begin{cfa} 1932 1918 struct S { … … 2008 1994 The symbol \lstinline+^+ is used for the destructor name because it was the last binary operator that could be used in a unary context.}. 2009 1995 The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = `{` 2, 3 `}`@. 2010 Like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @?{}(x, ...)@ or @^{}(x, ...)@.1996 Like other \CFA operators, these names represent the syntax used to explicitly call the constructor or destructor, \eg @s{...}@ or @^s{...}@. 2011 1997 The constructor and destructor have return type @void@, and the first parameter is a reference to the object type to be constructed or destructed. 2012 1998 While the first parameter is informally called the @this@ parameter, as in object-oriented languages, any variable name may be used. 2013 Both constructors and destructors allow additional paramete s after the @this@ parameter for specifying values for initialization/de-initialization\footnote{1999 Both constructors and destructors allow additional parameters after the @this@ parameter for specifying values for initialization/de-initialization\footnote{ 2014 2000 Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not deallocate.}. 2015 2001 \begin{cfa} … … 2018 2004 void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$ 2019 2005 { 2020 VLA x; $\C{// implicit: ?\{\}( x );}$2021 } $\C{// implicit: ?\^{}\{\}( x );}$2006 VLA x; $\C{// implicit:\ \ x\{\};}$ 2007 } $\C{// implicit:\ \textasciicircum{}x\{\};}$ 2022 2008 \end{cfa} 2023 2009 @VLA@ is a \newterm{managed type}\footnote{ … … 2044 2030 appropriate care is taken to not recursively call the copy constructor when initializing the second parameter. 2045 2031 2046 \CFA constructors may be explicitly call , like Java, and destructors may be explicitly called, like \CC.2032 \CFA constructors may be explicitly called, like Java, and destructors may be explicitly called, like \CC. 2047 2033 Explicit calls to constructors double as a \CC-style \emph{placement syntax}, useful for construction of member fields in user-defined constructors and reuse of existing storage allocations. 2048 While existing call syntax works for explicit calls to constructors and destructors, \CFA also provides a more concise \newterm{operator syntax} for both:2034 Like the other operators in \CFA, there is a concise syntax for constructor/destructor function calls: 2049 2035 \begin{cfa} 2050 2036 { 2051 2037 VLA x, y = { 20, 0x01 }, z = y; $\C{// z points to y}$ 2052 // ?{}( x ); ?{}( y, 20, 0x01 ); ?{}( z, y );2038 // x{}; y{ 20, 0x01 }; z{ z, y }; 2053 2039 ^x{}; $\C{// deallocate x}$ 2054 2040 x{}; $\C{// reallocate x}$ … … 2057 2043 y{ x }; $\C{// reallocate y, points to x}$ 2058 2044 x{}; $\C{// reallocate x, not pointing to y}$ 2059 // ^?{}(z); ^?{}(y); ^?{}(x);2045 // ^z{}; ^y{}; ^x{}; 2060 2046 } 2061 2047 \end{cfa} … … 2078 2064 In these cases, \CFA provides the initialization syntax \lstinline|S x `@=` {}|, and the object becomes unmanaged, so implicit constructor and destructor calls are not generated. 2079 2065 Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg \lstinline|VLA a @= { 0, 0x0 }|, with the usual C initialization semantics. 2080 The same syntax can be used in a compound literal, \eg \lstinline|a = VLA`@`{ 0, 0x0 }|, to create a C-style literal.2066 The same syntax can be used in a compound literal, \eg \lstinline|a = (VLA)`@`{ 0, 0x0 }|, to create a C-style literal. 2081 2067 The point of \lstinline|@=| is to provide a migration path from legacy C code to \CFA, by providing a mechanism to incrementally convert to implicit initialization. 2082 2068 … … 2134 2120 2135 2121 In C, @0@ has the special property that it is the only ``false'' value; 2136 fromthe standard, any value that compares equal to @0@ is false, while any value that compares unequal to @0@ is true.2122 by the standard, any value that compares equal to @0@ is false, while any value that compares unequal to @0@ is true. 2137 2123 As such, an expression @x@ in any boolean context (such as the condition of an @if@ or @while@ statement, or the arguments to @&&@, @||@, or @?:@\,) can be rewritten as @x != 0@ without changing its semantics. 2138 2124 Operator overloading in \CFA provides a natural means to implement this truth-value comparison for arbitrary types, but the C type system is not precise enough to distinguish an equality comparison with @0@ from an equality comparison with an arbitrary integer or pointer. … … 2169 2155 \lstDeleteShortInline@% 2170 2156 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{\hspace{2\parindentlnth}}l@{\hspace{2\parindentlnth}}l@{}} 2171 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{postfix function}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{constant}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{variable/expression}} & \multicolumn{1}{c}{\textbf{postfix pointer}} \\2157 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{postfix function}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{constant}} & \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{variable/expression}} & \multicolumn{1}{c@{}}{\textbf{postfix pointer}} \\ 2172 2158 \begin{cfa} 2173 2159 int |?`h|( int s ); … … 2214 2200 \lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}} 2215 2201 \lstDeleteShortInline@% 2216 \begin{tabular}{@{}l@{\hspace{ 2\parindentlnth}}l@{}}2217 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\2202 \begin{tabular}{@{}l@{\hspace{1.25\parindentlnth}}l@{}} 2203 \multicolumn{1}{@{}c@{\hspace{1.25\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{\CC}} \\ 2218 2204 \begin{cfa} 2219 2205 struct W { … … 2259 2245 W w, heavy = { 20 }; 2260 2246 w = 155|_lb|; 2261 w = 0b1111|_lb|; // error,binary unsupported2247 // binary unsupported 2262 2248 w = 0${\color{red}\LstBasicStyle{'}}$233|_lb|; // quote separator 2263 2249 w = 0x9b|_kg|; … … 2289 2275 \lstDeleteShortInline@% 2290 2276 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 2291 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{Definition}} & \multicolumn{1}{c}{\textbf{Usage}} \\2277 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{Definition}} & \multicolumn{1}{c@{}}{\textbf{Usage}} \\ 2292 2278 \begin{cfa} 2293 2279 const short int `MIN` = -32768; … … 2307 2293 \begin{cquote} 2308 2294 \lstDeleteShortInline@% 2309 \begin{tabular}{@{}l@{\hspace{ 2\parindentlnth}}l@{}}2310 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\2295 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}} 2296 \multicolumn{1}{@{}c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 2311 2297 \begin{cfa} 2312 2298 MIN 2313 2314 2299 MAX 2315 2316 2300 PI 2317 2301 E … … 2319 2303 & 2320 2304 \begin{cfa} 2321 SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, 2322 LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN 2323 SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, 2324 LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX 2305 CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN 2306 UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX 2325 2307 M_PI, M_PIl 2326 2308 M_E, M_El … … 2338 2320 \lstDeleteShortInline@% 2339 2321 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 2340 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{Definition}} & \multicolumn{1}{c}{\textbf{Usage}} \\2322 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{Definition}} & \multicolumn{1}{c@{}}{\textbf{Usage}} \\ 2341 2323 \begin{cfa} 2342 2324 float `log`( float x ); … … 2357 2339 \lstDeleteShortInline@% 2358 2340 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 2359 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\2341 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 2360 2342 \begin{cfa} 2361 2343 log … … 2385 2367 \lstDeleteShortInline@% 2386 2368 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 2387 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{Definition}} & \multicolumn{1}{c}{\textbf{Usage}} \\2369 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{Definition}} & \multicolumn{1}{c@{}}{\textbf{Usage}} \\ 2388 2370 \begin{cfa} 2389 2371 unsigned int `abs`( int ); … … 2404 2386 \lstDeleteShortInline@% 2405 2387 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 2406 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\2388 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 2407 2389 \begin{cfa} 2408 2390 abs … … 2427 2409 an allocation with a specified character. 2428 2410 \item[resize] 2429 an existing allocation to decrease d or increasedits size.2411 an existing allocation to decrease or increase its size. 2430 2412 In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation is copied. 2431 2413 For an increase in storage size, new storage after the copied data may be filled. … … 2441 2423 2442 2424 \begin{table} 2425 \caption{Storage-Management Operations} 2426 \label{t:StorageManagementOperations} 2443 2427 \centering 2444 2428 \lstDeleteShortInline@% … … 2460 2444 \lstDeleteShortInline~% 2461 2445 \lstMakeShortInline@% 2462 \caption{Storage-Management Operations}2463 \label{t:StorageManagementOperations}2464 2446 \end{table} 2465 2447 2466 2448 \begin{figure} 2467 2449 \centering 2468 \begin{cquote} 2469 \begin{cfa}[aboveskip=0pt] 2450 \begin{cfa}[aboveskip=0pt,xleftmargin=0pt] 2470 2451 size_t dim = 10; $\C{// array dimension}$ 2471 2452 char fill = '\xff'; $\C{// initialization fill value}$ … … 2473 2454 \end{cfa} 2474 2455 \lstDeleteShortInline@% 2475 \begin{tabular}{@{}l@{\hspace{ 2\parindentlnth}}l@{}}2476 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\2477 \begin{cfa} 2456 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}} 2457 \multicolumn{1}{@{}c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 2458 \begin{cfa}[xleftmargin=-10pt] 2478 2459 ip = alloc(); 2479 2460 ip = alloc( fill ); … … 2490 2471 & 2491 2472 \begin{cfa} 2492 ip = (int *)malloc( sizeof( int ) ); 2493 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) ); 2494 ip = (int *)malloc( dim * sizeof( int ) ); 2495 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) ); 2496 ip = (int *)realloc( ip, 2 * dim * sizeof( int ) ); 2497 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); 2498 memset( ip, fill, 4 * dim * sizeof( int ) ); 2499 ip = memalign( 16, sizeof( int ) ); 2500 ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) ); 2501 ip = memalign( 16, dim * sizeof( int ) ); 2502 ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) ); 2503 \end{cfa} 2504 \end{tabular} 2505 \lstMakeShortInline@% 2506 \end{cquote} 2473 ip = (int *)malloc( sizeof(int) ); 2474 ip = (int *)malloc( sizeof(int) ); memset( ip, fill, sizeof(int) ); 2475 ip = (int *)malloc( dim * sizeof(int) ); 2476 ip = (int *)malloc( sizeof(int) ); memset( ip, fill, dim * sizeof(int) ); 2477 ip = (int *)realloc( ip, 2 * dim * sizeof(int) ); 2478 ip = (int *)realloc( ip, 4 * dim * sizeof(int) ); memset( ip, fill, 4 * dim * sizeof(int)); 2479 2480 ip = memalign( 16, sizeof(int) ); 2481 ip = memalign( 16, sizeof(int) ); memset( ip, fill, sizeof(int) ); 2482 ip = memalign( 16, dim * sizeof(int) ); 2483 ip = memalign( 16, dim * sizeof(int) ); memset( ip, fill, dim * sizeof(int) ); 2484 \end{cfa} 2485 \end{tabular} 2486 \lstMakeShortInline@% 2507 2487 \caption{\CFA versus C Storage-Allocation} 2508 2488 \label{f:StorageAllocation} … … 2517 2497 S * as = anew( dim, 2, 3 ); $\C{// each array element initialized to 2, 3}$ 2518 2498 \end{cfa} 2519 Note, \CC can only initializ ationarray elements via the default constructor.2499 Note, \CC can only initialize array elements via the default constructor. 2520 2500 2521 2501 Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap. … … 2534 2514 \lstDeleteShortInline@% 2535 2515 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 2536 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\2516 \multicolumn{1}{@{}c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{\CC}} \\ 2537 2517 \begin{cfa} 2538 2518 int x = 1, y = 2, z = 3; … … 2589 2569 \end{cquote} 2590 2570 There is a weak similarity between the \CFA logical-or operator and the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output. 2591 2571 \begin{comment} 2592 2572 The implicit separator character (space/blank) is a separator not a terminator. 2593 2573 The rules for implicitly adding the separator are: … … 2608 2588 }% 2609 2589 \end{itemize} 2590 \end{comment} 2610 2591 There are functions to set and get the separator string, and manipulators to toggle separation on and off in the middle of output. 2611 2592 … … 2622 2603 \centering 2623 2604 \lstDeleteShortInline@% 2624 \begin{tabular}{@{}l@{\hspace{ 2\parindentlnth}}@{\hspace{2\parindentlnth}}l@{}}2625 \multicolumn{1}{ c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{2\parindentlnth}}c}{\textbf{C}} \\2605 \begin{tabular}{@{}l@{\hspace{3\parindentlnth}}l@{}} 2606 \multicolumn{1}{@{}c@{\hspace{3\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 2626 2607 \begin{cfa} 2627 2608 #include <gmp> … … 2656 2637 2657 2638 2658 \section{ Evaluation}2639 \section{Polymorphism Evaluation} 2659 2640 \label{sec:eval} 2660 2641 2661 Though \CFA provides significant added functionality over C, these features have a low runtime penalty. 2662 In fact, \CFA's features for generic programming can enable faster runtime execution than idiomatic @void *@-based C code. 2663 This claim is demonstrated through a set of generic-code-based micro-benchmarks in C, \CFA, and \CC (see stack implementations in Appendix~\ref{sec:BenchmarkStackImplementations}). 2642 \CFA adds parametric polymorphism to C. 2643 A runtime evaluation is performed to compare the cost of alternative styles of polymorphism. 2644 The goal is to compare just the underlying mechanism for implementing different kinds of polymorphism. 2645 % Though \CFA provides significant added functionality over C, these features have a low runtime penalty. 2646 % In fact, it is shown that \CFA's generic programming can enable faster runtime execution than idiomatic @void *@-based C code. 2647 The experiment is a set of generic-stack micro-benchmarks~\cite{CFAStackEvaluation} in C, \CFA, and \CC (see implementations in Appendix~\ref{sec:BenchmarkStackImplementations}). 2664 2648 Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks should show little runtime variance, differing only in length and clarity of source code. 2665 2649 A more illustrative comparison measures the costs of idiomatic usage of each language's features. … … 2692 2676 \end{figure} 2693 2677 2694 The structure of each benchmark implemented is: C with @void *@-based polymorphism, \CFA with the presented features, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV.2678 The structure of each benchmark implemented is: C with @void *@-based polymorphism, \CFA with parametric polymorphism, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV. 2695 2679 The \CCV variant illustrates an alternative object-oriented idiom where all objects inherit from a base @object@ class, mimicking a Java-like interface; 2696 2680 hence runtime checks are necessary to safely down-cast objects. 2697 2681 The most notable difference among the implementations is in memory layout of generic types: \CFA and \CC inline the stack and pair elements into corresponding list and pair nodes, while C and \CCV lack such a capability and instead must store generic objects via pointers to separately-allocated objects. 2698 Note that the C benchmark uses unchecked casts as there is no runtime mechanism to perform such checks, while \CFA and \CC provide type-safety statically.2682 Note, the C benchmark uses unchecked casts as C has no runtime mechanism to perform such checks, while \CFA and \CC provide type-safety statically. 2699 2683 2700 2684 Figure~\ref{fig:eval} and Table~\ref{tab:eval} show the results of running the benchmark in Figure~\ref{fig:BenchmarkTest} and its C, \CC, and \CCV equivalents. … … 2711 2695 2712 2696 \begin{table} 2713 \centering2714 2697 \caption{Properties of benchmark code} 2715 2698 \label{tab:eval} 2699 \centering 2716 2700 \newcommand{\CT}[1]{\multicolumn{1}{c}{#1}} 2717 2701 \begin{tabular}{rrrrr} … … 2726 2710 The C and \CCV variants are generally the slowest with the largest memory footprint, because of their less-efficient memory layout and the pointer-indirection necessary to implement generic types; 2727 2711 this inefficiency is exacerbated by the second level of generic types in the pair benchmarks. 2728 By contrast, the \CFA and \CC variants run in roughly equivalent time for both the integer and pair of @short@ and @char@ because the storage layout is equivalent, with the inlined libraries (\ie no separate compilation) and greater maturity of the \CC compiler contributing to its lead.2712 By contrast, the \CFA and \CC variants run in roughly equivalent time for both the integer and pair because of equivalent storage layout, with the inlined libraries (\ie no separate compilation) and greater maturity of the \CC compiler contributing to its lead. 2729 2713 \CCV is slower than C largely due to the cost of runtime type-checking of down-casts (implemented with @dynamic_cast@); 2730 The outlier in the graph for \CFA, pop @pair@, results from the complexity of the generated-C polymorphic code. 2731 The gcc compiler is unable to optimize some dead code and condense nested calls; a compiler designed for \CFA could easily perform these optimizations. 2714 The outlier for \CFA, pop @pair@, results from the complexity of the generated-C polymorphic code. 2715 The gcc compiler is unable to optimize some dead code and condense nested calls; 2716 a compiler designed for \CFA could easily perform these optimizations. 2732 2717 Finally, the binary size for \CFA is larger because of static linking with the \CFA libraries. 2733 2718 … … 2741 2726 Line-count is a fairly rough measure of code complexity; 2742 2727 another important factor is how much type information the programmer must specify manually, especially where that information is not compiler-checked. 2743 Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointer arguments and format codes, or \CCV, with its extensive use of un type-checked downcasts, \eg @object@ to @integer@ when popping a stack.2728 Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointer arguments and format codes, or \CCV, with its extensive use of un-type-checked downcasts, \eg @object@ to @integer@ when popping a stack. 2744 2729 To quantify this manual typing, the ``redundant type annotations'' line in Table~\ref{tab:eval} counts the number of lines on which the type of a known variable is respecified, either as a format specifier, explicit downcast, type-specific function, or by name in a @sizeof@, struct literal, or @new@ expression. 2745 2730 The \CC benchmark uses two redundant type annotations to create a new stack nodes, while the C and \CCV benchmarks have several such annotations spread throughout their code. 2746 2731 The \CFA benchmark is able to eliminate all redundant type annotations through use of the polymorphic @alloc@ function discussed in Section~\ref{sec:libraries}. 2747 2732 2733 We conjecture these results scale across most generic data-types as the underlying polymorphism implement is constant. 2734 2748 2735 2749 2736 \section{Related Work} … … 2751 2738 2752 2739 \subsection{Polymorphism} 2740 2741 ML~\cite{ML} was the first language to support parametric polymorphism. 2742 Like \CFA, it supports universal type parameters, but not the use of assertions and traits to constrain type arguments. 2743 Haskell~\cite{Haskell10} combines ML-style polymorphism, polymorphic data types, and type inference with the notion of type classes, collections of overloadable methods that correspond in intent to traits in \CFA. 2744 Unlike \CFA, Haskell requires an explicit association between types and their classes that specifies the implementation of operations. 2745 These associations determine the functions that are assertion arguments for particular combinations of class and type, in contrast to \CFA where the assertion arguments are selected at function call sites based upon the set of operations in scope at that point. 2746 Haskell also severely restricts the use of overloading: an overloaded name can only be associated with a single class, and methods with overloaded names can only be defined as part of instance declarations. 2753 2747 2754 2748 \CC provides three disjoint polymorphic extensions to C: overloading, inheritance, and templates. … … 2804 2798 Go does not have tuples but supports MRVF. 2805 2799 Java's variadic functions appear similar to C's but are type-safe using homogeneous arrays, which are less useful than \CFA's heterogeneously-typed variadic functions. 2806 Tuples are a fundamental abstraction in most functional programming languages, such as Standard ML~\cite{sml} and~\cite{Scala}, which decompose tuples using pattern matching.2800 Tuples are a fundamental abstraction in most functional programming languages, such as Standard ML~\cite{sml}, Haskell, and Scala~\cite{Scala}, which decompose tuples using pattern matching. 2807 2801 2808 2802 … … 2835 2829 Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable. 2836 2830 2837 There is ongoing work on a wide range of \CFA features, including arrays with size, runtime type-information, virtual functions, user-defined conversions, concurrent primitives, and modules. 2838 While all examples in the paper compile and run, a public beta-release of \CFA will take another 8--12 months to finalize these extensions. 2839 There are also interesting future directions for the polymorphism design. 2840 Notably, \CC template functions trade compile time and code bloat for optimal runtime of individual instantiations of polymorphic functions. 2841 \CFA polymorphic functions use dynamic virtual-dispatch; 2842 the runtime overhead of this approach is low, but not as low as inlining, and it may be beneficial to provide a mechanism for performance-sensitive code. 2831 While all examples in the paper compile and run, a public beta-release of \CFA will take 6--8 months to reduce compilation time, provide better debugging, and add a few more libraries. 2832 There is also new work on a number of \CFA features, including arrays with size, runtime type-information, virtual functions, user-defined conversions, and modules. 2833 While \CFA polymorphic functions use dynamic virtual-dispatch with low runtime overhead (see Section~\ref{sec:eval}), it is not as low as \CC template-inlining. 2834 Hence it may be beneficial to provide a mechanism for performance-sensitive code. 2843 2835 Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types (\CC template specialization). 2844 2836 These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat. … … 2849 2841 2850 2842 The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, Thierry Delisle, Andrew Beach and Brice Dobry on the features described in this paper, and thank Magnus Madsen for feedback on the writing. 2851 This work is supported by a corporate partnership with Huawei Ltd.\ (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr are partially funded by the Natural Sciences and Engineering Research Council of Canada. 2852 2853 2843 Funding for this project has been provided by Huawei Ltd.\ (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr are partially funded by the Natural Sciences and Engineering Research Council of Canada. 2844 2845 {% 2846 \fontsize{9bp}{12bp}\selectfont% 2854 2847 \bibliography{pl} 2855 2848 }% 2856 2849 2857 2850 \appendix
Note: See TracChangeset
for help on using the changeset viewer.