Changeset a722c7a for doc/papers/general
- Timestamp:
- Feb 9, 2018, 3:33:55 PM (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:
- 92f8e18, bede27b
- Parents:
- 565a3d6f
- Location:
- doc/papers/general
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Makefile
r565a3d6f ra722c7a 18 18 19 19 FIGURES = ${addsuffix .tex, \ 20 Cdecl \ 20 21 } 21 22 -
doc/papers/general/Paper.tex
r565a3d6f ra722c7a 102 102 \makeatother 103 103 104 \newenvironment{cquote}{% 105 \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindent\rightmargin\leftmargin}% 106 \item\relax 107 }{% 108 \endlist 109 }% cquote 110 104 111 % CFA programming language, based on ANSI C (with some gcc additions) 105 112 \lstdefinelanguage{CFA}[ANSI]{C}{ … … 227 234 int forty_two = identity( 42 ); $\C{// T is bound to int, forty\_two == 42}$ 228 235 \end{lstlisting} 229 The @identity@ function above can be applied to any complete \ emph{object type} (or @otype@).236 The @identity@ function above can be applied to any complete \newterm{object type} (or @otype@). 230 237 The type variable @T@ is transformed into a set of additional implicit parameters encoding sufficient information about @T@ to create and return a variable of that type. 231 238 The \CFA implementation passes the size and alignment of the type represented by an @otype@ parameter, as well as an assignment operator, constructor, copy constructor and destructor. 232 If this extra information is not needed, \eg for a pointer, the type parameter can be declared as a \ emph{data type} (or @dtype@).239 If this extra information is not needed, \eg for a pointer, the type parameter can be declared as a \newterm{data type} (or @dtype@). 233 240 234 241 In \CFA, the polymorphism runtime-cost is spread over each polymorphic call, due to passing more arguments to polymorphic functions; … … 236 243 A design advantage is that, unlike \CC template-functions, \CFA polymorphic-functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat. 237 244 238 Since bare polymorphic-types provide a restricted set of available operations, \CFA provides a \ emph{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable.245 Since bare polymorphic-types provide a restricted set of available operations, \CFA provides a \newterm{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable. 239 246 For example, the function @twice@ can be defined using the \CFA syntax for operator overloading: 240 247 \begin{lstlisting} … … 316 323 \subsection{Traits} 317 324 318 \CFA provides \ emph{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:325 \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: 319 326 \begin{lstlisting} 320 327 trait summable( otype T ) { … … 340 347 Given the information provided for an @otype@, variables of polymorphic type can be treated as if they were a complete type: stack-allocatable, default or copy-initialized, assigned, and deleted. 341 348 342 In summation, the \CFA type-system uses \ emph{nominal typing} for concrete types, matching with the C type-system, and \emph{structural typing} for polymorphic types.349 In summation, the \CFA type-system uses \newterm{nominal typing} for concrete types, matching with the C type-system, and \newterm{structural typing} for polymorphic types. 343 350 Hence, trait names play no part in type equivalence; 344 351 the names are simply macros for a list of polymorphic assertions, which are expanded at usage sites. … … 385 392 Furthermore, writing and using preprocessor macros can be unnatural and inflexible. 386 393 387 \CC, Java, and other languages use \ emph{generic types} to produce type-safe abstract data-types.394 \CC, Java, and other languages use \newterm{generic types} to produce type-safe abstract data-types. 388 395 \CFA also implements generic types that integrate efficiently and naturally with the existing polymorphic functions, while retaining backwards compatibility with C and providing separate compilation. 389 396 However, for known concrete parameters, the generic-type definition can be inlined, like \CC templates. … … 406 413 \end{lstlisting} 407 414 408 \CFA classifies generic types as either \ emph{concrete} or \emph{dynamic}.415 \CFA classifies generic types as either \newterm{concrete} or \newterm{dynamic}. 409 416 Concrete types have a fixed memory layout regardless of type parameters, while dynamic types vary in memory layout depending on their type parameters. 410 A type may have polymorphic parameters but still be concrete, called \ emph{dtype-static}.417 A type may have polymorphic parameters but still be concrete, called \newterm{dtype-static}. 411 418 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. 412 419 … … 445 452 Though \CFA implements concrete generic-types efficiently, it also has a fully general system for dynamic generic types. 446 453 As mentioned in Section~\ref{sec:poly-fns}, @otype@ function parameters (in fact all @sized@ polymorphic parameters) come with implicit size and alignment parameters provided by the caller. 447 Dynamic generic-types also have an \ emph{offset array} containing structure-member offsets.454 Dynamic generic-types also have an \newterm{offset array} containing structure-member offsets. 448 455 A dynamic generic-union needs no such offset array, as all members are at offset 0, but size and alignment are still necessary. 449 456 Access to members of a dynamic structure is provided at runtime via base-displacement addressing with the structure pointer and the member offset (similar to the @offsetof@ macro), moving a compile-time offset calculation to runtime. … … 458 465 For instance, modularity is generally provided in C by including an opaque forward-declaration of a structure and associated accessor and mutator functions in a header file, with the actual implementations in a separately-compiled @.c@ file. 459 466 \CFA supports this pattern for generic types, but the caller does not know the actual layout or size of the dynamic generic-type, and only holds it by a pointer. 460 The \CFA translator automatically generates \ emph{layout functions} for cases where the size, alignment, and offset array of a generic struct cannot be passed into a function from that function's caller.467 The \CFA translator automatically generates \newterm{layout functions} for cases where the size, alignment, and offset array of a generic struct cannot be passed into a function from that function's caller. 461 468 These layout functions take as arguments pointers to size and alignment variables and a caller-allocated array of member offsets, as well as the size and alignment of all @sized@ parameters to the generic structure (un@sized@ parameters are forbidden from being used in a context that affects layout). 462 469 Results of these layout functions are cached so that they are only computed once per type per function. %, as in the example below for @pair@. … … 482 489 Since @pair(T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the fields of both pairs and the arguments to the comparison function match in type. 483 490 484 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \ emph{tag-structures}.491 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \newterm{tag-structures}. 485 492 Sometimes information is only used for type-checking and can be omitted at runtime, \eg: 486 493 \begin{lstlisting} … … 538 545 The addition of multiple-return-value functions (MRVF) are useless without a syntax for accepting multiple values at the call-site. 539 546 The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly. 540 As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \ emph{tuple}.541 542 However, functions also use \ emph{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF), \eg:547 As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \newterm{tuple}. 548 549 However, functions also use \newterm{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF), \eg: 543 550 \begin{lstlisting} 544 551 printf( "%d %d\n", div( 13, 5 ) ); $\C{// return values seperated into arguments}$ … … 573 580 printf( "%d %d\n", qr ); 574 581 \end{lstlisting} 575 \CFA also supports \ emph{tuple indexing} to access single components of a tuple expression:582 \CFA also supports \newterm{tuple indexing} to access single components of a tuple expression: 576 583 \begin{lstlisting} 577 584 [int, int] * p = &qr; $\C{// tuple pointer}$ … … 616 623 \subsection{Tuple Assignment} 617 624 618 An assignment where the left side is a tuple type is called \ emph{tuple assignment}.619 There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called \ emph{multiple} and \emph{mass assignment}, respectively.625 An assignment where the left side is a tuple type is called \newterm{tuple assignment}. 626 There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called \newterm{multiple} and \newterm{mass assignment}, respectively. 620 627 %\lstDeleteShortInline@% 621 628 %\par\smallskip … … 651 658 \subsection{Member Access} 652 659 653 It is also possible to access multiple fields from a single expression using a \ emph{member-access}.660 It is also possible to access multiple fields from a single expression using a \newterm{member-access}. 654 661 The result is a single tuple-valued expression whose type is the tuple of the types of the members, \eg: 655 662 \begin{lstlisting} … … 781 788 Matching against a @ttype@ parameter consumes all remaining argument components and packages them into a tuple, binding to the resulting tuple of types. 782 789 In a given parameter list, there must be at most one @ttype@ parameter that occurs last, which matches normal variadic semantics, with a strong feeling of similarity to \CCeleven variadic templates. 783 As such, @ttype@ variables are also called \ emph{argument packs}.790 As such, @ttype@ variables are also called \newterm{argument packs}. 784 791 785 792 Like variadic templates, the main way to manipulate @ttype@ polymorphic functions is via recursion. … … 853 860 \subsection{Implementation} 854 861 855 Tuples are implemented in the \CFA translator via a transformation into \ emph{generic types}.862 Tuples are implemented in the \CFA translator via a transformation into \newterm{generic types}. 856 863 For each $N$, the first time an $N$-tuple is seen in a scope a generic type with $N$ type parameters is generated, \eg: 857 864 \begin{lstlisting} … … 904 911 Similarly, tuple member expressions are recursively expanded into a list of member access expressions. 905 912 906 Expressions that may contain side effects are made into \ emph{unique expressions} before being expanded by the flattening conversion.913 Expressions that may contain side effects are made into \newterm{unique expressions} before being expanded by the flattening conversion. 907 914 Each unique expression is assigned an identifier and is guaranteed to be executed exactly once: 908 915 \begin{lstlisting} … … 1091 1098 % In object-oriented programming, there is an implicit first parameter, often names @self@ or @this@, which is elided. 1092 1099 % In any programming language, some functions have a naturally close relationship with a particular data type. 1093 % Object-oriented programming allows this close relationship to be codified in the language by making such functions \ emph{class methods} of their related data type.1100 % 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. 1094 1101 % Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type. 1095 1102 % 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. … … 1205 1212 C declaration syntax is notoriously confusing and error prone. 1206 1213 For example, many C programmers are confused by a declaration as simple as: 1207 \begin{ flushleft}1214 \begin{cquote} 1208 1215 \lstDeleteShortInline@% 1209 1216 \begin{tabular}{@{}ll@{}} … … 1215 1222 \end{tabular} 1216 1223 \lstMakeShortInline@% 1217 \end{ flushleft}1224 \end{cquote} 1218 1225 Is this an array of 5 pointers to integers or a pointer to an array of 5 integers? 1219 The fact this declaration is unclear to many C programmers means there areproductivity and safety issues even for basic programs.1226 If there is any doubt, it implies productivity and safety issues even for basic programs. 1220 1227 Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site. 1221 1228 For example, a routine returning a pointer to an array of integers is defined and used in the following way: … … 1231 1238 In the following example, \R{red} is the base type and \B{blue} is qualifiers. 1232 1239 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. 1233 \begin{ quote}1240 \begin{cquote} 1234 1241 \lstDeleteShortInline@% 1235 1242 \lstset{moredelim=**[is][\color{blue}]{+}{+}} … … 1249 1256 \end{tabular} 1250 1257 \lstMakeShortInline@% 1251 \end{ quote}1258 \end{cquote} 1252 1259 The only exception is bit field specification, which always appear to the right of the base type. 1253 % Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()©are used to indicate a routine parameter.1260 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a routine parameter. 1254 1261 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list. 1255 For instance, variables ©x© and ©y©of type pointer to integer are defined in \CFA as follows:1256 \begin{ quote}1262 For instance, variables @x@ and @y@ of type pointer to integer are defined in \CFA as follows: 1263 \begin{cquote} 1257 1264 \lstDeleteShortInline@% 1258 1265 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} … … 1267 1274 \end{tabular} 1268 1275 \lstMakeShortInline@% 1269 \end{ quote}1276 \end{cquote} 1270 1277 The downside of this semantics is the need to separate regular and pointer declarations: 1271 \begin{ quote}1278 \begin{cquote} 1272 1279 \lstDeleteShortInline@% 1273 1280 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} … … 1284 1291 \end{tabular} 1285 1292 \lstMakeShortInline@% 1286 \end{ quote}1293 \end{cquote} 1287 1294 which is prescribing a safety benefit. 1288 1295 Other examples are: 1289 \begin{ quote}1296 \begin{cquote} 1290 1297 \lstDeleteShortInline@% 1291 1298 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} … … 1325 1332 \end{tabular} 1326 1333 \lstMakeShortInline@% 1327 \end{ quote}1328 1329 All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg:1330 \begin{ quote}1334 \end{cquote} 1335 1336 All type qualifiers, \eg @const@, @volatile@, etc., are used in the normal way with the new declarations and also appear left to right, \eg: 1337 \begin{cquote} 1331 1338 \lstDeleteShortInline@% 1332 1339 \begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}} … … 1348 1355 \end{tabular} 1349 1356 \lstMakeShortInline@% 1350 \end{ quote}1351 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}1357 \end{cquote} 1358 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} 1352 1359 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: 1353 \begin{ quote}1360 \begin{cquote} 1354 1361 \lstDeleteShortInline@% 1355 1362 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} … … 1371 1378 \end{tabular} 1372 1379 \lstMakeShortInline@% 1373 \end{ quote}1374 1375 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©:1376 \begin{ quote}1380 \end{cquote} 1381 1382 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@: 1383 \begin{cquote} 1377 1384 \lstDeleteShortInline@% 1378 1385 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 1379 1386 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1380 1387 \begin{cfa} 1381 y = ( `* int`)x;1382 i = sizeof( `[ 5 ] * int`);1388 y = (* int)x; 1389 i = sizeof([ 5 ] * int); 1383 1390 \end{cfa} 1384 1391 & 1385 1392 \begin{cfa} 1386 y = ( `int *`)x;1387 i = sizeof( `int * [ 5 ]`);1393 y = (int *)x; 1394 i = sizeof(int * [ 5 ]); 1388 1395 \end{cfa} 1389 1396 \end{tabular} 1390 1397 \lstMakeShortInline@% 1391 \end{ quote}1398 \end{cquote} 1392 1399 1393 1400 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. 1394 1401 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 1395 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems.1402 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems. 1396 1403 1397 1404 1398 1405 \subsection{References} 1399 1406 1400 All variables in C have an \emph{address}, a \emph{value}, and a \emph{type}; at the position in the program's memory denoted by the address, there exists a sequence of bits (the value), with the length and semantic meaning of this bit sequence defined by the type. 1401 The C type system does not always track the relationship between a value and its address; a value that does not have a corresponding address is called a \emph{rvalue} (for ``right-hand value''), while a value that does have an address is called a \emph{lvalue} (for ``left-hand value''); in @int x; x = 42;@ the variable expression @x@ on the left-hand-side of the assignment is a lvalue, while the constant expression @42@ on the right-hand-side of the assignment is a rvalue. 1402 Which address a value is located at is sometimes significant; the imperative programming paradigm of C relies on the mutation of values at specific addresses. 1403 Within a lexical scope, lvalue exressions can be used in either their \emph{address interpretation} to determine where a mutated value should be stored or in their \emph{value interpretation} to refer to their stored value; in @x = y;@ in @{ int x, y = 7; x = y; }@, @x@ is used in its address interpretation, while y is used in its value interpretation. 1404 Though this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \emph{pointer types} to serve a similar purpose. 1405 In C, for any type @T@ there is a pointer type @T*@, the value of which is the address of a value of type @T@; a pointer rvalue can be explicitly \emph{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, while the rvalue representing the address of a lvalue can be obtained with the address-of operator @&?@. 1407 All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type}; 1408 at the position in the program's memory denoted by the address, there exists a sequence of bits (the value), with the length and semantic meaning of this bit sequence defined by the type. 1409 The C type-system does not always track the relationship between a value and its address; 1410 a value that does not have a corresponding address is called a \newterm{rvalue} (for ``right-hand value''), while a value that does have an address is called a \newterm{lvalue} (for ``left-hand value''). 1411 For example, in @int x; x = 42;@ the variable expression @x@ on the left-hand-side of the assignment is a lvalue, while the constant expression @42@ on the right-hand-side of the assignment is a rvalue. 1412 In imperative programming, the address of a value is used for both reading and writing (mutating) a value. 1413 1414 Within a lexical scope, lvalue expressions have an \newterm{address interpretation} for writing a value or a \newterm{value interpretation} to read a value. 1415 For example, in @x = y@, @x@ has an address interpretation, while @y@ has a value interpretation. 1416 Though this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \newterm{pointer types} to serve a similar purpose. 1417 In C, for any type @T@ there is a pointer type @T *@, the value of which is the address of a value of type @T@. 1418 A pointer rvalue can be explicitly \newterm{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, while the rvalue representing the address of a lvalue can be obtained with the address-of operator @&?@. 1406 1419 1407 1420 \begin{cfa} 1408 1421 int x = 1, y = 2, * p1, * p2, ** p3; 1409 p1 = &x; 1410 p2 = &y; 1411 p3 = &p1; 1422 p1 = &x; $\C{// p1 points to x}$ 1423 p2 = &y; $\C{// p2 points to y}$ 1424 p3 = &p1; $\C{// p3 points to p1}$ 1412 1425 *p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15); 1413 1426 \end{cfa} … … 1415 1428 Unfortunately, the dereference and address-of operators introduce a great deal of syntactic noise when dealing with pointed-to values rather than pointers, as well as the potential for subtle bugs. 1416 1429 For both brevity and clarity, it would be desirable to have the compiler figure out how to elide the dereference operators in a complex expression such as the assignment to @*p2@ above. 1417 However, since C defines a number of forms of \ emph{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a user programmer may write one when they mean the other, and precluding any simple algorithm for elision of dereference operators.1430 However, since C defines a number of forms of \newterm{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a user programmer may write one when they mean the other, and precluding any simple algorithm for elision of dereference operators. 1418 1431 To solve these problems, \CFA introduces reference types @T&@; a @T&@ has exactly the same value as a @T*@, but where the @T*@ takes the address interpretation by default, a @T&@ takes the value interpretation by default, as below: 1419 1432 1420 1433 \begin{cfa} 1421 in xx = 1, y = 2, & r1, & r2, && r3;1434 int x = 1, y = 2, & r1, & r2, && r3; 1422 1435 &r1 = &x; $\C{// r1 points to x}$ 1423 1436 &r2 = &y; $\C{// r2 points to y}$ … … 1441 1454 This allows \CFA references to be default-initialized (\eg to a null pointer), and also to point to different addresses throughout their lifetime. 1442 1455 This rebinding is accomplished without adding any new syntax to \CFA, but simply by extending the existing semantics of the address-of operator in C. 1456 1443 1457 In C, the address of a lvalue is always a rvalue, as in general that address is not stored anywhere in memory, and does not itself have an address. 1444 1458 In \CFA, the address of a @T&@ is a lvalue @T*@, as the address of the underlying @T@ is stored in the reference, and can thus be mutated there. … … 1454 1468 if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T `*`&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\ \ie @T@ pointer with $l$ references (@&@ symbols). 1455 1469 \end{itemize} 1456 1457 1470 Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them in user code can be made based solely on convenience. 1471 1458 1472 By analogy to pointers, \CFA references also allow cv-qualifiers: 1459 1473 … … 1474 1488 1475 1489 More generally, this initialization of references from lvalues rather than pointers is an instance of a ``lvalue-to-reference'' conversion rather than an elision of the address-of operator; this conversion can actually be used in any context in \CFA an implicit conversion would be allowed. 1476 Similarly, use of a the value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, anal agous to the @T *@ to @const T *@ conversion in standard C.1490 Similarly, use of a the value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, analogous to the @T *@ to @const T *@ conversion in standard C. 1477 1491 The final reference conversion included in \CFA is ``rvalue-to-reference'' conversion, implemented by means of an implicit temporary. 1478 1492 When an rvalue is used to initialize a reference, it is instead used to initialize a hidden temporary value with the same lexical scope as the reference, and the reference is initialized to the address of this temporary. 1479 1493 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. 1480 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \emph{const hell} problem, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers. 1494 \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. 1495 1481 1496 1482 1497 \subsection{Constructors and Destructors} … … 1484 1499 One of the strengths of C is the control over memory management it gives programmers, allowing resource release to be more consistent and precisely timed than is possible with garbage-collected memory management. 1485 1500 However, this manual approach to memory management is often verbose, and it is useful to manage resources other than memory (\eg file handles) using the same mechanism as memory. 1486 \CC is well-known for an approach to manual memory management that addresses both these issues, Resource Aquisition Is Initialization (RAII), implemented by means of special \ emph{constructor} and \emph{destructor} functions; we have implemented a similar feature in \CFA.1501 \CC is well-known for an approach to manual memory management that addresses both these issues, Resource Aquisition Is Initialization (RAII), implemented by means of special \newterm{constructor} and \newterm{destructor} functions; we have implemented a similar feature in \CFA. 1487 1502 While RAII is a common feature of object-oriented programming languages, its inclusion in \CFA does not violate the design principle that \CFA retain the same procedural paradigm as C. 1488 1503 In particular, \CFA does not implement class-based encapsulation: neither the constructor nor any other function has privileged access to the implementation details of a type, except through the translation-unit-scope method of opaque structs provided by C. … … 1516 1531 \end{cfa} 1517 1532 1518 In the example above, a \ emph{default constructor} (\ie one with no parameters besides the @this@ parameter) and destructor are defined for the @Array@ struct, a dynamic array of @int@.1519 @Array@ is an example of a \ emph{managed type} in \CFA, a type with a non-trivial constructor or destructor, or with a field of a managed type.1533 In the example above, a \newterm{default constructor} (\ie one with no parameters besides the @this@ parameter) and destructor are defined for the @Array@ struct, a dynamic array of @int@. 1534 @Array@ is an example of a \newterm{managed type} in \CFA, a type with a non-trivial constructor or destructor, or with a field of a managed type. 1520 1535 As in the example, all instances of managed types are implicitly constructed upon allocation, and destructed upon deallocation; this ensures proper initialization and cleanup of resources contained in managed types, in this case the @data@ array on the heap. 1521 1536 The exact details of the placement of these implicit constructor and destructor calls are omitted here for brevity, the interested reader should consult \cite{Schluntz17}. 1522 1537 1523 1538 Constructor calls are intended to seamlessly integrate with existing C initialization syntax, providing a simple and familiar syntax to veteran C programmers and allowing constructor calls to be inserted into legacy C code with minimal code changes. 1524 As such, \CFA also provides syntax for \ emph{copy initialization} and \emph{initialization parameters}:1539 As such, \CFA also provides syntax for \newterm{copy initialization} and \newterm{initialization parameters}: 1525 1540 1526 1541 \begin{cfa} … … 1537 1552 In addition to initialization syntax, \CFA provides two ways to explicitly call constructors and destructors. 1538 1553 Explicit calls to constructors double as a placement syntax, useful for construction of member fields in user-defined constructors and reuse of large storage allocations. 1539 While the existing function-call syntax works for explicit calls to constructors and destructors, \CFA also provides a more concise \ emph{operator syntax} for both:1554 While the existing function-call syntax works for explicit calls to constructors and destructors, \CFA also provides a more concise \newterm{operator syntax} for both: 1540 1555 1541 1556 \begin{cfa} … … 1554 1569 For compatibility with C, a copy constructor from the first union member type is also defined. 1555 1570 For @struct@ types, each of the four functions are implicitly defined to call their corresponding functions on each member of the struct. 1556 To better simulate the behaviour of C initializers, a set of \ emph{field constructors} is also generated for structures.1571 To better simulate the behaviour of C initializers, a set of \newterm{field constructors} is also generated for structures. 1557 1572 A constructor is generated for each non-empty prefix of a structure's member-list which copy-constructs the members passed as parameters and default-constructs the remaining members. 1558 1573 To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all field constructors for that type are hidden from expression resolution; similarly, the generated default constructor is hidden upon declaration of any constructor. … … 1560 1575 1561 1576 In rare situations user programmers may not wish to have constructors and destructors called; in these cases, \CFA provides an ``escape hatch'' to not call them. 1562 If a variable is initialized using the syntax \lstinline|S x @= {}| it will be an \ emph{unmanaged object}, and will not have constructors or destructors called.1577 If a variable is initialized using the syntax \lstinline|S x @= {}| it will be an \newterm{unmanaged object}, and will not have constructors or destructors called. 1563 1578 Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg \lstinline|Array a @= { 0, 0x0 }|, with the usual C initialization semantics. 1564 1579 In addition to the expressive power, \lstinline|@=| provides a simple path for migrating legacy C code to \CFA, by providing a mechanism to incrementally convert initializers; the \CFA design team decided to introduce a new syntax for this escape hatch because we believe that our RAII implementation will handle the vast majority of code in a desirable way, and we wished to maintain familiar syntax for this common case.
Note: See TracChangeset
for help on using the changeset viewer.