Changes in doc/user/user.tex [9e0a360:9e6d652]
- File:
-
- 1 edited
-
doc/user/user.tex (modified) (146 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
r9e0a360 r9e6d652 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : S at Jun 15 16:29:45201914 %% Update Count : 3 84713 %% Last Modified On : Sun May 5 18:24:50 2019 14 %% Update Count : 3489 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 254 254 \begin{lstlisting} 255 255 ®forall( otype T )® T identity( T val ) { return val; } 256 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§256 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§ 257 257 \end{lstlisting} 258 258 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. … … 282 282 283 283 double key = 5.0, vals[10] = { /* 10 sorted floating values */ }; 284 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§284 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§ 285 285 \end{lstlisting} 286 286 which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers: … … 291 291 292 292 forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) { 293 T * result = bsearch( key, arr, size ); §\C{// call first version}§294 return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§295 296 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§293 T * result = bsearch( key, arr, size ); §\C{// call first version}§ 294 return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§ 295 296 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§ 297 297 int posn = bsearch( 5.0, vals, 10 ); 298 298 \end{lstlisting} … … 306 306 \begin{lstlisting} 307 307 forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 308 int * ip = malloc(); §\C{// select type and size from left-hand side}§308 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 309 309 double * dp = malloc(); 310 310 struct S {...} * sp = malloc(); … … 318 318 \begin{cfa} 319 319 char ®abs®( char ); 320 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§320 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§ 321 321 long int ®abs®( long int ); 322 322 long long int ®abs®( long long int ); … … 426 426 \begin{cfa} 427 427 #ifndef __CFORALL__ 428 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§428 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§ 429 429 #else 430 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§430 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§ 431 431 #endif 432 432 \end{cfa} … … 512 512 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 513 513 \begin{cfa} 514 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§514 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ 515 515 double ®`®forall®`® = 3.5; 516 516 \end{cfa} … … 523 523 \begin{cfa} 524 524 // include file uses the CFA keyword "with". 525 #if ! defined( with ) §\C{// nesting ?}§526 #define with ®`®with®`® §\C{// make keyword an identifier}§525 #if ! defined( with ) §\C{// nesting ?}§ 526 #define with ®`®with®`® §\C{// make keyword an identifier}§ 527 527 #define __CFA_BFD_H__ 528 528 #endif 529 529 530 ®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§530 ®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§ 531 531 ® 532 532 #if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§ … … 544 544 Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg: 545 545 \begin{cfa} 546 2®_®147®_®483®_®648; §\C{// decimal constant}§547 56®_®ul; §\C{// decimal unsigned long constant}§548 0®_®377; §\C{// octal constant}§549 0x®_®ff®_®ff; §\C{// hexadecimal constant}§550 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§551 3.141®_®592®_®654; §\C{// floating constant}§552 10®_®e®_®+1®_®00; §\C{// floating constant}§553 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§554 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§555 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§546 2®_®147®_®483®_®648; §\C{// decimal constant}§ 547 56®_®ul; §\C{// decimal unsigned long constant}§ 548 0®_®377; §\C{// octal constant}§ 549 0x®_®ff®_®ff; §\C{// hexadecimal constant}§ 550 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§ 551 3.141®_®592®_®654; §\C{// floating constant}§ 552 10®_®e®_®+1®_®00; §\C{// floating constant}§ 553 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§ 554 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§ 555 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 556 556 \end{cfa} 557 557 The rules for placement of underscores are: … … 612 612 (Does not make sense for ©do©-©while©.) 613 613 \begin{cfa} 614 if ( ®int x = f()® ) ... §\C{// x != 0}§615 if ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§616 if ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§614 if ( ®int x = f()® ) ... §\C{// x != 0}§ 615 if ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§ 616 if ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§ 617 617 if ( ®struct S { int i; } x = { f() }; x.i < 4® ) §\C{// relational expression}§ 618 618 619 while ( ®int x = f()® ) ... §\C{// x != 0}§620 while ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§619 while ( ®int x = f()® ) ... §\C{// x != 0}§ 620 while ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§ 621 621 while ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§ 622 622 while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... §\C{// relational expression}§ … … 892 892 \begin{cfa} 893 893 switch ( x ) { 894 ®int y = 1;® §\C{// unreachable initialization}§895 ®x = 7;® §\C{// unreachable code without label/branch}§894 ®int y = 1;® §\C{// unreachable initialization}§ 895 ®x = 7;® §\C{// unreachable code without label/branch}§ 896 896 case 0: ... 897 897 ... 898 ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§898 ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§ 899 899 z = 2; 900 900 case 1: 901 ®x = z;® §\C{// without fall through, z is uninitialized}§901 ®x = z;® §\C{// without fall through, z is uninitialized}§ 902 902 } 903 903 \end{cfa} … … 937 937 ®case 5: 938 938 ... 939 ®fallthru®; §\C{// explicit fall through}§939 ®fallthru®; §\C{// explicit fall through}§ 940 940 case 7: 941 941 ... 942 ®break® §\C{// explicit end of switch (redundant)}§942 ®break® §\C{// explicit end of switch (redundant)}§ 943 943 default: 944 944 j = 3; … … 961 961 \begin{cfa} 962 962 switch ( x ) { 963 ®int i = 0;® §\C{// allowed only at start}§963 ®int i = 0;® §\C{// allowed only at start}§ 964 964 case 0: 965 965 ... 966 ®int j = 0;® §\C{// disallowed}§966 ®int j = 0;® §\C{// disallowed}§ 967 967 case 1: 968 968 { 969 ®int k = 0;® §\C{// allowed at different nesting levels}§969 ®int k = 0;® §\C{// allowed at different nesting levels}§ 970 970 ... 971 ®case 2:® §\C{// disallow case in nested statements}§971 ®case 2:® §\C{// disallow case in nested statements}§ 972 972 } 973 973 ... … … 1019 1019 \begin{cfa} 1020 1020 switch ( i ) { 1021 case ®1~5:® §\C{// 1, 2, 3, 4, 5}§1021 case ®1~5:® §\C{// 1, 2, 3, 4, 5}§ 1022 1022 ... 1023 case ®10~15:® §\C{// 10, 11, 12, 13, 14, 15}§1023 case ®10~15:® §\C{// 10, 11, 12, 13, 14, 15}§ 1024 1024 ... 1025 1025 } … … 1152 1152 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: 1153 1153 \begin{cfa} 1154 struct S { §\C{// aggregate}§1155 char c; §\C{// fields}§1154 struct S { §\C{// aggregate}§ 1155 char c; §\C{// fields}§ 1156 1156 int i; 1157 1157 double d; … … 1162 1162 \begin{cfa} 1163 1163 void f( S s ) { 1164 ®s.®c; ®s.®i; ®s.®d; §\C{// access containing fields}§1164 ®s.®c; ®s.®i; ®s.®d; §\C{// access containing fields}§ 1165 1165 } 1166 1166 \end{cfa} … … 1169 1169 \begin{C++} 1170 1170 struct S { 1171 char c; §\C{// fields}§1171 char c; §\C{// fields}§ 1172 1172 int i; 1173 1173 double d; 1174 void f() { §\C{// implicit ``this'' aggregate}§1175 ®this->®c; ®this->®i; ®this->®d; §\C{// access containing fields}§1174 void f() { §\C{// implicit ``this'' aggregate}§ 1175 ®this->®c; ®this->®i; ®this->®d; §\C{// access containing fields}§ 1176 1176 } 1177 1177 } … … 1181 1181 \begin{cfa} 1182 1182 struct T { double m, n; }; 1183 int S::f( T & t ) { §\C{// multiple aggregate parameters}§1184 c; i; d; §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§1185 ®t.®m; ®t.®n; §\C{// must qualify}§1183 int S::f( T & t ) { §\C{// multiple aggregate parameters}§ 1184 c; i; d; §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§ 1185 ®t.®m; ®t.®n; §\C{// must qualify}§ 1186 1186 } 1187 1187 \end{cfa} … … 1190 1190 Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block. 1191 1191 \begin{cfa} 1192 void f( S & this ) ®with ( this )® { §\C{// with statement}§1193 c; i; d; §\C{\color{red}// this.c, this.i, this.d}§1192 void f( S & this ) ®with ( this )® { §\C{// with statement}§ 1193 c; i; d; §\C{\color{red}// this.c, this.i, this.d}§ 1194 1194 } 1195 1195 \end{cfa} 1196 1196 with the generality of opening multiple aggregate-parameters: 1197 1197 \begin{cfa} 1198 void f( S & s, T & t ) ®with ( s, t )® { §\C{// multiple aggregate parameters}§1199 c; i; d; §\C{\color{red}// s.c, s.i, s.d}§1200 m; n; §\C{\color{red}// t.m, t.n}§1198 void f( S & s, T & t ) ®with ( s, t )® { §\C{// multiple aggregate parameters}§ 1199 c; i; d; §\C{\color{red}// s.c, s.i, s.d}§ 1200 m; n; §\C{\color{red}// t.m, t.n}§ 1201 1201 } 1202 1202 \end{cfa} … … 1220 1220 struct T { int ®i®; int k; int m; } t, w; 1221 1221 with ( s, t ) { 1222 j + k; §\C{// unambiguous, s.j + t.k}§1223 m = 5.0; §\C{// unambiguous, t.m = 5.0}§1224 m = 1; §\C{// unambiguous, s.m = 1}§1225 int a = m; §\C{// unambiguous, a = s.i }§1226 double b = m; §\C{// unambiguous, b = t.m}§1227 int c = s.i + t.i; §\C{// unambiguous, qualification}§1228 (double)m; §\C{// unambiguous, cast}§1222 j + k; §\C{// unambiguous, s.j + t.k}§ 1223 m = 5.0; §\C{// unambiguous, t.m = 5.0}§ 1224 m = 1; §\C{// unambiguous, s.m = 1}§ 1225 int a = m; §\C{// unambiguous, a = s.i }§ 1226 double b = m; §\C{// unambiguous, b = t.m}§ 1227 int c = s.i + t.i; §\C{// unambiguous, qualification}§ 1228 (double)m; §\C{// unambiguous, cast}§ 1229 1229 } 1230 1230 \end{cfa} … … 1236 1236 There is an interesting problem between parameters and the function-body ©with©, \eg: 1237 1237 \begin{cfa} 1238 void ?{}( S & s, int i ) with ( s ) { §\C{// constructor}§1239 ®s.i = i;® j = 3; m = 5.5; §\C{// initialize fields}§1238 void ?{}( S & s, int i ) with ( s ) { §\C{// constructor}§ 1239 ®s.i = i;® j = 3; m = 5.5; §\C{// initialize fields}§ 1240 1240 } 1241 1241 \end{cfa} … … 1256 1256 Finally, a cast may be used to disambiguate among overload variables in a ©with© expression: 1257 1257 \begin{cfa} 1258 with ( w ) { ... } §\C{// ambiguous, same name and no context}§1259 with ( (S)w ) { ... } §\C{// unambiguous, cast}§1258 with ( w ) { ... } §\C{// ambiguous, same name and no context}§ 1259 with ( (S)w ) { ... } §\C{// unambiguous, cast}§ 1260 1260 \end{cfa} 1261 1261 and ©with© expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate: 1262 1262 % \begin{cfa} 1263 1263 % struct S { int i, j; } sv; 1264 % with ( sv ) { §\C{// implicit reference}§1264 % with ( sv ) { §\C{// implicit reference}§ 1265 1265 % S & sr = sv; 1266 % with ( sr ) { §\C{// explicit reference}§1266 % with ( sr ) { §\C{// explicit reference}§ 1267 1267 % S * sp = &sv; 1268 % with ( *sp ) { §\C{// computed reference}§1269 % i = 3; j = 4; §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§1268 % with ( *sp ) { §\C{// computed reference}§ 1269 % i = 3; j = 4; §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§ 1270 1270 % } 1271 % i = 2; j = 3; §\C{\color{red}// sr.i, sr.j}§1271 % i = 2; j = 3; §\C{\color{red}// sr.i, sr.j}§ 1272 1272 % } 1273 % i = 1; j = 2; §\C{\color{red}// sv.i, sv.j}§1273 % i = 1; j = 2; §\C{\color{red}// sv.i, sv.j}§ 1274 1274 % } 1275 1275 % \end{cfa} … … 1279 1279 class C { 1280 1280 int i, j; 1281 int mem() { §\C{\color{red}// implicit "this" parameter}§1282 i = 1; §\C{\color{red}// this->i}§1283 j = 2; §\C{\color{red}// this->j}§1281 int mem() { §\C{\color{red}// implicit "this" parameter}§ 1282 i = 1; §\C{\color{red}// this->i}§ 1283 j = 2; §\C{\color{red}// this->j}§ 1284 1284 } 1285 1285 } … … 1288 1288 \begin{cfa} 1289 1289 struct S { int i, j; }; 1290 int mem( S & ®this® ) { §\C{// explicit "this" parameter}§1291 ®this.®i = 1; §\C{// "this" is not elided}§1290 int mem( S & ®this® ) { §\C{// explicit "this" parameter}§ 1291 ®this.®i = 1; §\C{// "this" is not elided}§ 1292 1292 ®this.®j = 2; 1293 1293 } … … 1297 1297 \CFA provides a ©with© clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided the "©this.©" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references. 1298 1298 \begin{cfa} 1299 int mem( S & this ) ®with( this )® { §\C{// with clause}§1300 i = 1; §\C{\color{red}// this.i}§1301 j = 2; §\C{\color{red}// this.j}§1299 int mem( S & this ) ®with( this )® { §\C{// with clause}§ 1300 i = 1; §\C{\color{red}// this.i}§ 1301 j = 2; §\C{\color{red}// this.j}§ 1302 1302 } 1303 1303 \end{cfa} … … 1316 1316 struct S1 { ... } s1; 1317 1317 struct S2 { ... } s2; 1318 ®with( s1 )® { §\C{// with statement}§1318 ®with( s1 )® { §\C{// with statement}§ 1319 1319 // access fields of s1 without qualification 1320 ®with s2® { §\C{// nesting}§1320 ®with s2® { §\C{// nesting}§ 1321 1321 // access fields of s1 and s2 without qualification 1322 1322 } … … 1373 1373 Non-local transfer can cause stack unwinding, \ie non-local routine termination, depending on the kind of raise. 1374 1374 \begin{cfa} 1375 exception_t E {}; §\C{// exception type}§1375 exception_t E {}; §\C{// exception type}§ 1376 1376 void f(...) { 1377 ... throw E{}; ... §\C{// termination}§1378 ... throwResume E{}; ... §\C{// resumption}§1377 ... throw E{}; ... §\C{// termination}§ 1378 ... throwResume E{}; ... §\C{// resumption}§ 1379 1379 } 1380 1380 try { … … 1442 1442 For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way: 1443 1443 \begin{cfa} 1444 int ®(*®f®())[®5®]® {...}; §\C{// definition}§1445 ... ®(*®f®())[®3®]® += 1; §\C{// usage}§1444 int ®(*®f®())[®5®]® {...}; §\C{// definition}§ 1445 ... ®(*®f®())[®3®]® += 1; §\C{// usage}§ 1446 1446 \end{cfa} 1447 1447 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}). … … 1635 1635 *x = 3; // implicit dereference 1636 1636 int * ®const® y = (int *)104; 1637 *y = *x; // implicit dereference1637 *y = *x; // implicit dereference 1638 1638 \end{cfa} 1639 1639 \end{tabular} … … 1649 1649 \hline 1650 1650 \begin{cfa} 1651 lda r1,100 // load address of x1652 ld r2,(r1) // load value of x1653 lda r3,104 // load address of y1654 st r2,(r3) // store x into y1651 lda r1,100 // load address of x 1652 ld r2,(r1) // load value of x 1653 lda r3,104 // load address of y 1654 st r2,(r3) // store x into y 1655 1655 \end{cfa} 1656 1656 & 1657 1657 \begin{cfa} 1658 1658 1659 ld r2,(100) // load value of x1660 1661 st r2,(104) // store x into y1659 ld r2,(100) // load value of x 1660 1661 st r2,(104) // store x into y 1662 1662 \end{cfa} 1663 1663 \end{tabular} … … 1673 1673 \begin{cfa} 1674 1674 int x, y, ®*® p1, ®*® p2, ®**® p3; 1675 p1 = ®&®x; // p1 points to x1676 p2 = p1; // p2 points to x1677 p1 = ®&®y; // p1 points to y1678 p3 = &p2; // p3 points to p21675 p1 = ®&®x; // p1 points to x 1676 p2 = p1; // p2 points to x 1677 p1 = ®&®y; // p1 points to y 1678 p3 = &p2; // p3 points to p2 1679 1679 \end{cfa} 1680 1680 & … … 1687 1687 For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage 1688 1688 \begin{cfa} 1689 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§1689 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§ 1690 1690 \end{cfa} 1691 1691 Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation. … … 1695 1695 In C, objects of pointer type always manipulate the pointer object's address: 1696 1696 \begin{cfa} 1697 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§1698 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§1697 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§ 1698 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§ 1699 1699 \end{cfa} 1700 1700 even though the assignment to ©p2© is likely incorrect, and the programmer probably meant: 1701 1701 \begin{cfa} 1702 p1 = p2; §\C{// pointer address assignment}§1703 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§1702 p1 = p2; §\C{// pointer address assignment}§ 1703 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§ 1704 1704 \end{cfa} 1705 1705 The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©). … … 1718 1718 \begin{cfa} 1719 1719 int x, y, ®&® r1, ®&® r2, ®&&® r3; 1720 ®&®r1 = &x; §\C{// r1 points to x}§1721 ®&®r2 = &r1; §\C{// r2 points to x}§1722 ®&®r1 = &y; §\C{// r1 points to y}§1723 ®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§1720 ®&®r1 = &x; §\C{// r1 points to x}§ 1721 ®&®r2 = &r1; §\C{// r2 points to x}§ 1722 ®&®r1 = &y; §\C{// r1 points to y}§ 1723 ®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§ 1724 1724 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§ 1725 1725 \end{cfa} … … 1737 1737 For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}): 1738 1738 \begin{cfa} 1739 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§1739 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§ 1740 1740 \end{cfa} 1741 1741 Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}): 1742 1742 \begin{cfa} 1743 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§1743 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§ 1744 1744 \end{cfa} 1745 1745 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth. … … 1749 1749 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2, 1750 1750 &r1 = x, &&r2 = r1, &&&r3 = r2; 1751 ***p3 = 3; §\C{// change x}§1752 r3 = 3; §\C{// change x, ***r3}§1753 **p3 = ...; §\C{// change p1}§1754 &r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§1755 *p3 = ...; §\C{// change p2}§1756 &&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§1757 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§1751 ***p3 = 3; §\C{// change x}§ 1752 r3 = 3; §\C{// change x, ***r3}§ 1753 **p3 = ...; §\C{// change p1}§ 1754 &r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§ 1755 *p3 = ...; §\C{// change p2}§ 1756 &&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§ 1757 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§ 1758 1758 \end{cfa} 1759 1759 Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types. … … 1762 1762 As for a pointer type, a reference type may have qualifiers: 1763 1763 \begin{cfa} 1764 const int cx = 5; §\C{// cannot change cx;}§1765 const int & cr = cx; §\C{// cannot change what cr points to}§1766 ®&®cr = &cx; §\C{// can change cr}§1767 cr = 7; §\C{// error, cannot change cx}§1768 int & const rc = x; §\C{// must be initialized}§1769 ®&®rc = &x; §\C{// error, cannot change rc}§1770 const int & const crc = cx; §\C{// must be initialized}§1771 crc = 7; §\C{// error, cannot change cx}§1772 ®&®crc = &cx; §\C{// error, cannot change crc}§1764 const int cx = 5; §\C{// cannot change cx;}§ 1765 const int & cr = cx; §\C{// cannot change what cr points to}§ 1766 ®&®cr = &cx; §\C{// can change cr}§ 1767 cr = 7; §\C{// error, cannot change cx}§ 1768 int & const rc = x; §\C{// must be initialized}§ 1769 ®&®rc = &x; §\C{// error, cannot change rc}§ 1770 const int & const crc = cx; §\C{// must be initialized}§ 1771 crc = 7; §\C{// error, cannot change cx}§ 1772 ®&®crc = &cx; §\C{// error, cannot change crc}§ 1773 1773 \end{cfa} 1774 1774 Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}: 1775 1775 \begin{cfa} 1776 int & const cr = *0; §\C{// where 0 is the int * zero}§1776 int & const cr = *0; §\C{// where 0 is the int * zero}§ 1777 1777 \end{cfa} 1778 1778 Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management: … … 1781 1781 cr = 5; 1782 1782 free( &cr ); 1783 cr = 7; §\C{// unsound pointer dereference}§1783 cr = 7; §\C{// unsound pointer dereference}§ 1784 1784 \end{cfa} 1785 1785 … … 1806 1806 \begin{cfa} 1807 1807 int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§ 1808 &ar[1] = &w; §\C{// change reference array element}§1809 typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§1810 typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§1811 sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§1812 sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§1808 &ar[1] = &w; §\C{// change reference array element}§ 1809 typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§ 1810 typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§ 1811 sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§ 1812 sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§ 1813 1813 \end{cfa} 1814 1814 … … 1827 1827 Therefore, for pointer/reference initialization, the initializing value must be an address not a value. 1828 1828 \begin{cfa} 1829 int * p = &x; §\C{// assign address of x}§1830 ®int * p = x;® §\C{// assign value of x}§1831 int & r = x; §\C{// must have address of x}§1829 int * p = &x; §\C{// assign address of x}§ 1830 ®int * p = x;® §\C{// assign value of x}§ 1831 int & r = x; §\C{// must have address of x}§ 1832 1832 \end{cfa} 1833 1833 Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given). … … 1838 1838 Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason. 1839 1839 \begin{cfa} 1840 int & f( int & r ); §\C{// reference parameter and return}§1841 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§1840 int & f( int & r ); §\C{// reference parameter and return}§ 1841 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§ 1842 1842 \end{cfa} 1843 1843 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©. … … 1866 1866 void f( int & r ); 1867 1867 void g( int * p ); 1868 f( 3 ); g( ®&®3 ); §\C{// compiler implicit generates temporaries}§1869 f( x + y ); g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§1868 f( 3 ); g( ®&®3 ); §\C{// compiler implicit generates temporaries}§ 1869 f( x + y ); g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§ 1870 1870 \end{cfa} 1871 1871 Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{ … … 1878 1878 \begin{cfa} 1879 1879 void f( int i ); 1880 void (* fp)( int ); §\C{// routine pointer}§1881 fp = f; §\C{// reference initialization}§1882 fp = &f; §\C{// pointer initialization}§1883 fp = *f; §\C{// reference initialization}§1884 fp(3); §\C{// reference invocation}§1885 (*fp)(3); §\C{// pointer invocation}§1880 void (* fp)( int ); §\C{// routine pointer}§ 1881 fp = f; §\C{// reference initialization}§ 1882 fp = &f; §\C{// pointer initialization}§ 1883 fp = *f; §\C{// reference initialization}§ 1884 fp(3); §\C{// reference invocation}§ 1885 (*fp)(3); §\C{// pointer invocation}§ 1886 1886 \end{cfa} 1887 1887 While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type. 1888 1888 Instead, a routine object should be referenced by a ©const© reference: 1889 1889 \begin{cfa} 1890 ®const® void (®&® fr)( int ) = f; §\C{// routine reference}§1891 fr = ... §\C{// error, cannot change code}§1892 &fr = ...; §\C{// changing routine reference}§1893 fr( 3 ); §\C{// reference call to f}§1894 (*fr)(3); §\C{// error, incorrect type}§1890 ®const® void (®&® fr)( int ) = f; §\C{// routine reference}§ 1891 fr = ... §\C{// error, cannot change code}§ 1892 &fr = ...; §\C{// changing routine reference}§ 1893 fr( 3 ); §\C{// reference call to f}§ 1894 (*fr)(3); §\C{// error, incorrect type}§ 1895 1895 \end{cfa} 1896 1896 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{ … … 1914 1914 int x, * px, ** ppx, *** pppx, **** ppppx; 1915 1915 int & rx = x, && rrx = rx, &&& rrrx = rrx ; 1916 x = rrrx; §\C[2.0in]{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§1917 px = &rrrx; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (\&x)}§1918 ppx = &&rrrx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (\&rx)}§1919 pppx = &&&rrrx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (\&rrx)}§1920 ppppx = &&&&rrrx; §\C{// starting from \&\&\&rrrx, \&\&\&\&rrrx is an rvalue with type int **** (\&rrrx)}§1916 x = rrrx; // rrrx is an lvalue with type int &&& (equivalent to x) 1917 px = &rrrx; // starting from rrrx, &rrrx is an rvalue with type int *&&& (&x) 1918 ppx = &&rrrx; // starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx) 1919 pppx = &&&rrrx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx) 1920 ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx) 1921 1921 \end{cfa} 1922 1922 The following example shows the second rule applied to different \Index{lvalue} contexts: … … 1924 1924 int x, * px, ** ppx, *** pppx; 1925 1925 int & rx = x, && rrx = rx, &&& rrrx = rrx ; 1926 rrrx = 2; §\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§1927 &rrrx = px; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (rx)}§1928 &&rrrx = ppx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (rrx)}§1929 &&&rrrx = pppx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (rrrx)}\CRT§1926 rrrx = 2; // rrrx is an lvalue with type int &&& (equivalent to x) 1927 &rrrx = px; // starting from rrrx, &rrrx is an rvalue with type int *&&& (rx) 1928 &&rrrx = ppx; // starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx) 1929 &&&rrrx = pppx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx) 1930 1930 \end{cfa} 1931 1931 … … 1940 1940 \begin{cfa} 1941 1941 int x; 1942 x + 1; §\C[2.0in]{// lvalue variable (int) converts to rvalue for expression}§1942 x + 1; // lvalue variable (int) converts to rvalue for expression 1943 1943 \end{cfa} 1944 1944 An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped. … … 1950 1950 \begin{cfa} 1951 1951 int x, &r = x, f( int p ); 1952 x = ®r® + f( ®r® ); §\C{// lvalue reference converts to rvalue}§1952 x = ®r® + f( ®r® ); // lvalue reference converts to rvalue 1953 1953 \end{cfa} 1954 1954 An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped. … … 1957 1957 lvalue to reference conversion: \lstinline[deletekeywords=lvalue]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references. 1958 1958 \begin{cfa} 1959 int x, &r = ®x®, f( int & p ); §\C{// lvalue variable (int) convert to reference (int \&)}§1960 f( ®x® ); §\C{// lvalue variable (int) convert to reference (int \&)}§1959 int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &) 1960 f( ®x® ); // lvalue variable (int) convert to reference (int &) 1961 1961 \end{cfa} 1962 1962 Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost. … … 1968 1968 \begin{cfa} 1969 1969 int x, & f( int & p ); 1970 f( ®x + 3® ); §\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}§1971 ®&f®(...) = &x; §\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT§1970 f( ®x + 3® ); // rvalue parameter (int) implicitly converts to lvalue temporary reference (int &) 1971 ®&f®(...) = &x; // rvalue result (int &) implicitly converts to lvalue temporary reference (int &) 1972 1972 \end{cfa} 1973 1973 In both case, modifications to the temporary are inaccessible (\Index{warning}). … … 2158 2158 in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in: 2159 2159 \begin{cfa} 2160 [§\,§] g(); §\C{// no input or output parameters}§2161 [ void ] g( void ); §\C{// no input or output parameters}§2160 [§\,§] g(); §\C{// no input or output parameters}§ 2161 [ void ] g( void ); §\C{// no input or output parameters}§ 2162 2162 \end{cfa} 2163 2163 … … 2177 2177 \begin{cfa} 2178 2178 typedef int foo; 2179 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§2179 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§ 2180 2180 \end{cfa} 2181 2181 The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo. … … 2185 2185 C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg: 2186 2186 \begin{cfa} 2187 [ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§2188 [ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§2187 [ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§ 2188 [ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§ 2189 2189 \end{cfa} 2190 2190 The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in: 2191 2191 \begin{cfa} 2192 2192 #define ptoa( n, d ) int (*n)[ d ] 2193 int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§2194 [ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§2193 int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§ 2194 [ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§ 2195 2195 \end{cfa} 2196 2196 Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms. … … 2214 2214 int z; 2215 2215 ... x = 0; ... y = z; ... 2216 ®return;® §\C{// implicitly return x, y}§2216 ®return;® §\C{// implicitly return x, y}§ 2217 2217 } 2218 2218 \end{cfa} … … 2224 2224 [ int x, int y ] f() { 2225 2225 ... 2226 } §\C{// implicitly return x, y}§2226 } §\C{// implicitly return x, y}§ 2227 2227 \end{cfa} 2228 2228 In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered. … … 2233 2233 [ int x, int y ] f( int, x, int y ) { 2234 2234 ... 2235 } §\C{// implicitly return x, y}§2235 } §\C{// implicitly return x, y}§ 2236 2236 \end{cfa} 2237 2237 This notation allows the compiler to eliminate temporary variables in nested routine calls. 2238 2238 \begin{cfa} 2239 [ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§2239 [ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§ 2240 2240 int a, b; 2241 2241 [a, b] = f( f( f( a, b ) ) ); … … 2251 2251 as well, parameter names are optional, \eg: 2252 2252 \begin{cfa} 2253 [ int x ] f (); §\C{// returning int with no parameters}§2254 [ * int ] g (int y); §\C{// returning pointer to int with int parameter}§2255 [ ] h ( int, char ); §\C{// returning no result with int and char parameters}§2256 [ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§2253 [ int x ] f (); §\C{// returning int with no parameters}§ 2254 [ * int ] g (int y); §\C{// returning pointer to int with int parameter}§ 2255 [ ] h ( int, char ); §\C{// returning no result with int and char parameters}§ 2256 [ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§ 2257 2257 \end{cfa} 2258 2258 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa). … … 2275 2275 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 2276 2276 \begin{cfa} 2277 * [ int x ] () fp; §\C{// pointer to routine returning int with no parameters}§2278 * [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§2279 * [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§2280 * [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}§2277 * [ int x ] () fp; §\C{// pointer to routine returning int with no parameters}§ 2278 * [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§ 2279 * [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§ 2280 * [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}§ 2281 2281 \end{cfa} 2282 2282 While parameter names are optional, \emph{a routine name cannot be specified}; 2283 2283 for example, the following is incorrect: 2284 2284 \begin{cfa} 2285 * [ int x ] f () fp; §\C{// routine name "f" is not allowed}§2285 * [ int x ] f () fp; §\C{// routine name "f" is not allowed}§ 2286 2286 \end{cfa} 2287 2287 … … 2306 2306 whereas a named (keyword) call may be: 2307 2307 \begin{cfa} 2308 p( z : 3, x : 4, y : 7 ); §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§2308 p( z : 3, x : 4, y : 7 ); §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§ 2309 2309 \end{cfa} 2310 2310 Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters. … … 2323 2323 For example, the following routine prototypes and definition are all valid. 2324 2324 \begin{cfa} 2325 void p( int, int, int ); §\C{// equivalent prototypes}§2325 void p( int, int, int ); §\C{// equivalent prototypes}§ 2326 2326 void p( int x, int y, int z ); 2327 2327 void p( int y, int x, int z ); 2328 2328 void p( int z, int y, int x ); 2329 void p( int q, int r, int s ) {} §\C{// match with this definition}§2329 void p( int q, int r, int s ) {} §\C{// match with this definition}§ 2330 2330 \end{cfa} 2331 2331 Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming. … … 2339 2339 int f( int x, double y ); 2340 2340 2341 f( j : 3, i : 4 ); §\C{// 1st f}§2342 f( x : 7, y : 8.1 ); §\C{// 2nd f}§2343 f( 4, 5 ); §\C{// ambiguous call}§2341 f( j : 3, i : 4 ); §\C{// 1st f}§ 2342 f( x : 7, y : 8.1 ); §\C{// 2nd f}§ 2343 f( 4, 5 ); §\C{// ambiguous call}§ 2344 2344 \end{cfa} 2345 2345 However, named arguments compound routine resolution in conjunction with conversions: 2346 2346 \begin{cfa} 2347 f( i : 3, 5.7 ); §\C{// ambiguous call ?}§2347 f( i : 3, 5.7 ); §\C{// ambiguous call ?}§ 2348 2348 \end{cfa} 2349 2349 Depending on the cost associated with named arguments, this call could be resolvable or ambiguous. … … 2359 2359 the allowable positional calls are: 2360 2360 \begin{cfa} 2361 p(); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§2362 p( 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§2363 p( 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§2364 p( 4, 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§2361 p(); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§ 2362 p( 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§ 2363 p( 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§ 2364 p( 4, 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§ 2365 2365 // empty arguments 2366 p( , 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§2367 p( 4, , 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§2368 p( 4, 4, ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§2369 p( 4, , ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§2370 p( , 4, ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§2371 p( , , 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§2372 p( , , ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§2366 p( , 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§ 2367 p( 4, , 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§ 2368 p( 4, 4, ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§ 2369 p( 4, , ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§ 2370 p( , 4, ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§ 2371 p( , , 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§ 2372 p( , , ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§ 2373 2373 \end{cfa} 2374 2374 Here the missing arguments are inserted from the default values in the parameter list. … … 2394 2394 Default values may only appear in a prototype versus definition context: 2395 2395 \begin{cfa} 2396 void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§2397 void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§2398 void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§2396 void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§ 2397 void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§ 2398 void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§ 2399 2399 \end{cfa} 2400 2400 The reason for this restriction is to allow separate compilation. … … 2421 2421 \begin{cfa} 2422 2422 void p( int x, int y = 2, int z = 3... ); 2423 p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§2424 p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§2423 p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§ 2424 p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§ 2425 2425 \end{cfa} 2426 2426 The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments; … … 2452 2452 Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as: 2453 2453 \begin{cfa} 2454 p( 1, /* default */, 5 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§2454 p( 1, /* default */, 5 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§ 2455 2455 \end{cfa} 2456 2456 … … 2465 2465 \begin{cfa} 2466 2466 struct { 2467 int f1; §\C{// named field}§2468 int f2 : 4; §\C{// named field with bit field size}§2469 int : 3; §\C{// unnamed field for basic type with bit field size}§2470 int ; §\C{// disallowed, unnamed field}§2471 int *; §\C{// disallowed, unnamed field}§2472 int (*)( int ); §\C{// disallowed, unnamed field}§2467 int f1; §\C{// named field}§ 2468 int f2 : 4; §\C{// named field with bit field size}§ 2469 int : 3; §\C{// unnamed field for basic type with bit field size}§ 2470 int ; §\C{// disallowed, unnamed field}§ 2471 int *; §\C{// disallowed, unnamed field}§ 2472 int (*)( int ); §\C{// disallowed, unnamed field}§ 2473 2473 }; 2474 2474 \end{cfa} … … 2478 2478 \begin{cfa} 2479 2479 struct { 2480 int , , ; §\C{// 3 unnamed fields}§2480 int , , ; §\C{// 3 unnamed fields}§ 2481 2481 } 2482 2482 \end{cfa} … … 2572 2572 const unsigned int size = 5; 2573 2573 int ia[size]; 2574 ... §\C{// assign values to array ia}§2575 qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§2574 ... §\C{// assign values to array ia}§ 2575 qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§ 2576 2576 { 2577 2577 ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§ 2578 qsort( ia, size ); §\C{// sort descending order by local redefinition}§2578 qsort( ia, size ); §\C{// sort descending order by local redefinition}§ 2579 2579 } 2580 2580 \end{cfa} … … 2584 2584 The following program in undefined in \CFA (and Indexc{gcc}) 2585 2585 \begin{cfa} 2586 [* [int]( int )] foo() { §\C{// int (* foo())( int )}§2586 [* [int]( int )] foo() { §\C{// int (* foo())( int )}§ 2587 2587 int ®i® = 7; 2588 2588 int bar( int p ) { 2589 ®i® += 1; §\C{// dependent on local variable}§2589 ®i® += 1; §\C{// dependent on local variable}§ 2590 2590 sout | ®i®; 2591 2591 } 2592 return bar; §\C{// undefined because of local dependence}§2592 return bar; §\C{// undefined because of local dependence}§ 2593 2593 } 2594 2594 int main() { 2595 * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§2595 * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§ 2596 2596 sout | fp( 3 ); 2597 2597 } … … 2606 2606 In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call. 2607 2607 \begin{cfa} 2608 f( ®2, x, 3 + i® ); §\C{// element list}§2608 f( ®2, x, 3 + i® ); §\C{// element list}§ 2609 2609 \end{cfa} 2610 2610 A list of elements is called a \newterm{tuple}, and is different from a \Index{comma expression}. … … 2623 2623 typedef struct { int quot, rem; } div_t; §\C[7cm]{// from include stdlib.h}§ 2624 2624 div_t div( int num, int den ); 2625 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§2626 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§2625 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§ 2626 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§ 2627 2627 \end{cfa} 2628 2628 This approach requires a name for the return type and fields, where \Index{naming} is a common programming-language issue. … … 2634 2634 For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value. 2635 2635 \begin{cfa} 2636 double modf( double x, double * i ); §\C{// from include math.h}§2637 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§2638 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§2636 double modf( double x, double * i ); §\C{// from include math.h}§ 2637 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§ 2638 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§ 2639 2639 \end{cfa} 2640 2640 This approach requires allocating storage for the return values, which complicates the call site with a sequence of variable declarations leading to the call. … … 2663 2663 When a function call is passed as an argument to another call, the best match of actual arguments to formal parameters is evaluated given all possible expression interpretations in the current scope. 2664 2664 \begin{cfa} 2665 void g( int, int ); §\C{// 1}§2666 void g( double, double ); §\C{// 2}§2667 g( div( 13, 5 ) ); §\C{// select 1}§2668 g( modf( 13.5 ) ); §\C{// select 2}§2665 void g( int, int ); §\C{// 1}§ 2666 void g( double, double ); §\C{// 2}§ 2667 g( div( 13, 5 ) ); §\C{// select 1}§ 2668 g( modf( 13.5 ) ); §\C{// select 2}§ 2669 2669 \end{cfa} 2670 2670 In this case, there are two overloaded ©g© routines. … … 2675 2675 The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call. 2676 2676 \begin{cfa} 2677 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§2678 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§2679 2680 [ double, double ] modf( double x ); §\C{// from include math}§2681 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§2677 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§ 2678 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§ 2679 2680 [ double, double ] modf( double x ); §\C{// from include math}§ 2681 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§ 2682 2682 \end{cfa} 2683 2683 This approach provides the benefits of compile-time checking for appropriate return statements as in aggregation, but without the required verbosity of declaring a new named type. … … 2689 2689 \begin{cfa} 2690 2690 int quot, rem; 2691 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§2692 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§2691 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§ 2692 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§ 2693 2693 \end{cfa} 2694 2694 Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call. … … 2716 2716 In \CFA, it is possible to overcome this restriction by declaring a \newterm{tuple variable}. 2717 2717 \begin{cfa} 2718 [int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§2719 printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§2718 [int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§ 2719 printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§ 2720 2720 \end{cfa} 2721 2721 It is now possible to match the multiple return-values to a single variable, in much the same way as \Index{aggregation}. … … 2723 2723 One way to access the individual components of a tuple variable is with assignment. 2724 2724 \begin{cfa} 2725 [ quot, rem ] = qr; §\C{// assign multiple variables}§2725 [ quot, rem ] = qr; §\C{// assign multiple variables}§ 2726 2726 \end{cfa} 2727 2727 … … 2746 2746 [int, double] * p; 2747 2747 2748 int y = x.0; §\C{// access int component of x}§2749 y = f().1; §\C{// access int component of f}§2750 p->0 = 5; §\C{// access int component of tuple pointed-to by p}§2751 g( x.1, x.0 ); §\C{// rearrange x to pass to g}§2752 double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§2748 int y = x.0; §\C{// access int component of x}§ 2749 y = f().1; §\C{// access int component of f}§ 2750 p->0 = 5; §\C{// access int component of tuple pointed-to by p}§ 2751 g( x.1, x.0 ); §\C{// rearrange x to pass to g}§ 2752 double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§ 2753 2753 \end{cfa} 2754 2754 Tuple-index expressions can occur on any tuple-typed expression, including tuple-returning functions, square-bracketed tuple expressions, and other tuple-index expressions, provided the retrieved component is also a tuple. … … 2817 2817 double y; 2818 2818 [int, double] z; 2819 [y, x] = 3.14; §\C{// mass assignment}§2819 [y, x] = 3.14; §\C{// mass assignment}§ 2820 2820 [x, y] = z; §\C{// multiple assignment}§ 2821 2821 z = 10; §\C{// mass assignment}§ 2822 z = [x, y]; §\C{// multiple assignment}§2822 z = [x, y]; §\C{// multiple assignment}§ 2823 2823 \end{cfa} 2824 2824 Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment. … … 2864 2864 double c, d; 2865 2865 [ void ] f( [ int, int ] ); 2866 f( [ c, a ] = [ b, d ] = 1.5 ); §\C{// assignments in parameter list}§2866 f( [ c, a ] = [ b, d ] = 1.5 ); // assignments in parameter list 2867 2867 \end{cfa} 2868 2868 The tuple expression begins with a mass assignment of ©1.5© into ©[b, d]©, which assigns ©1.5© into ©b©, which is truncated to ©1©, and ©1.5© into ©d©, producing the tuple ©[1, 1.5]© as a result. … … 2877 2877 \begin{cfa} 2878 2878 struct S; 2879 void ?{}(S *); §\C{// (1)}§2880 void ?{}(S *, int); §\C{// (2)}§2881 void ?{}(S * double); §\C{// (3)}§2882 void ?{}(S *, S); §\C{// (4)}§2883 2884 [S, S] x = [3, 6.28]; §\C{// uses (2), (3), specialized constructors}§2885 [S, S] y; §\C{// uses (1), (1), default constructor}§2886 [S, S] z = x.0; §\C{// uses (4), (4), copy constructor}§2879 void ?{}(S *); // (1) 2880 void ?{}(S *, int); // (2) 2881 void ?{}(S * double); // (3) 2882 void ?{}(S *, S); // (4) 2883 2884 [S, S] x = [3, 6.28]; // uses (2), (3), specialized constructors 2885 [S, S] y; // uses (1), (1), default constructor 2886 [S, S] z = x.0; // uses (4), (4), copy constructor 2887 2887 \end{cfa} 2888 2888 In this example, ©x© is initialized by the multiple constructor calls ©?{}(&x.0, 3)© and ©?{}(&x.1, 6.28)©, while ©y© is initialized by two default constructor calls ©?{}(&y.0)© and ©?{}(&y.1)©. … … 2925 2925 A member-access tuple may be used anywhere a tuple can be used, \eg: 2926 2926 \begin{cfa} 2927 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§2928 f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§2927 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§ 2928 f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§ 2929 2929 \end{cfa} 2930 2930 Note, the fields appearing in a record-field tuple may be specified in any order; … … 2936 2936 void f( double, long ); 2937 2937 2938 f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§2939 x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§2938 f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§ 2939 x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§ 2940 2940 [ long, int, long ] y = x.[ 2, 0, 2 ]; 2941 2941 \end{cfa} … … 2954 2954 \begin{cfa} 2955 2955 [ int, float, double ] f(); 2956 [ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§2956 [ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§ 2957 2957 \end{cfa} 2958 2958 … … 2967 2967 That is, a cast can be used to select the type of an expression when it is ambiguous, as in the call to an overloaded function. 2968 2968 \begin{cfa} 2969 int f(); §\C{// (1)}§2970 double f(); §\C{// (2)}§2971 2972 f(); §\C{// ambiguous - (1),(2) both equally viable}§2973 (int)f(); §\C{// choose (2)}§2969 int f(); // (1) 2970 double f(); // (2) 2971 2972 f(); // ambiguous - (1),(2) both equally viable 2973 (int)f(); // choose (2) 2974 2974 \end{cfa} 2975 2975 Since casting is a fundamental operation in \CFA, casts need to be given a meaningful interpretation in the context of tuples. … … 2979 2979 void g(); 2980 2980 2981 (void)f(); §\C{// valid, ignore results}§2982 (int)g(); §\C{// invalid, void cannot be converted to int}§2981 (void)f(); // valid, ignore results 2982 (int)g(); // invalid, void cannot be converted to int 2983 2983 2984 2984 struct A { int x; }; 2985 (struct A)f(); §\C{// invalid, int cannot be converted to A}§2985 (struct A)f(); // invalid, int cannot be converted to A 2986 2986 \end{cfa} 2987 2987 In C, line 4 is a valid cast, which calls ©f© and discards its result. … … 2999 2999 [int, [int, int], int] g(); 3000 3000 3001 ([int, double])f(); §\C{// (1) valid}§3002 ([int, int, int])g(); §\C{// (2) valid}§3003 ([void, [int, int]])g(); §\C{// (3) valid}§3004 ([int, int, int, int])g(); §\C{// (4) invalid}§3005 ([int, [int, int, int]])g(); §\C{// (5) invalid}§3001 ([int, double])f(); // (1) valid 3002 ([int, int, int])g(); // (2) valid 3003 ([void, [int, int]])g(); // (3) valid 3004 ([int, int, int, int])g(); // (4) invalid 3005 ([int, [int, int, int]])g(); // (5) invalid 3006 3006 \end{cfa} 3007 3007 … … 3063 3063 void f([int, int], int, int); 3064 3064 3065 f([0, 0], 0, 0); §\C{// no cost}§3066 f(0, 0, 0, 0); §\C{// cost for structuring}§3067 f([0, 0,], [0, 0]); §\C{// cost for flattening}§3068 f([0, 0, 0], 0); §\C{// cost for flattening and structuring}§3065 f([0, 0], 0, 0); // no cost 3066 f(0, 0, 0, 0); // cost for structuring 3067 f([0, 0,], [0, 0]); // cost for flattening 3068 f([0, 0, 0], 0); // cost for flattening and structuring 3069 3069 \end{cfa} 3070 3070 … … 3129 3129 [ unsigned int, char ] 3130 3130 [ double, double, double ] 3131 [ * int, int * ] §\C{// mix of CFA and ANSI}§3131 [ * int, int * ] §\C{// mix of CFA and ANSI}§ 3132 3132 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ] 3133 3133 \end{cfa} … … 3136 3136 Examples of declarations using tuple types are: 3137 3137 \begin{cfa} 3138 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§3139 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§3138 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§ 3139 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§ 3140 3140 [ [ int, int ] ] z ([ int, int ]); 3141 3141 \end{cfa} … … 3154 3154 [ int, int ] w1; 3155 3155 [ int, int, int ] w2; 3156 [ void ] f (int, int, int); §\C{// three input parameters of type int}§3157 [ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§3156 [ void ] f (int, int, int); /* three input parameters of type int */ 3157 [ void ] g ([ int, int, int ]); /* 3 element tuple as input */ 3158 3158 f( [ 1, 2, 3 ] ); 3159 3159 f( w1, 3 ); … … 3235 3235 [ int, int, int, int ] w = [ 1, 2, 3, 4 ]; 3236 3236 int x = 5; 3237 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§3237 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§ 3238 3238 \end{cfa} 3239 3239 Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values; … … 3323 3323 both these examples produce indeterminate results: 3324 3324 \begin{cfa} 3325 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§3326 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in righthand side of multiple assignment}§3325 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§ 3326 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in righthand side of multiple assignment}§ 3327 3327 \end{cfa} 3328 3328 … … 3346 3346 3347 3347 3348 \section{I/O Stream Library} 3349 \label{s:IOStreamLibrary} 3350 \index{input/output stream library} 3351 \index{stream library} 3352 3353 The goal of \CFA input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 3354 \CFA I/O combines ideas from C ©printf©, \CC, and Python. 3355 I/O can be unformatted or formatted. 3356 Unformatted means \CFA selects the output or input format for values that match with the type of a variable. 3357 Formatted means additional information is specified to augment how an output or input of value is interpreted. 3358 \CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators. 3359 \begin{itemize} 3360 \item 3361 ©printf© format codes are dense, making them difficult to read and remember. 3362 \CFA/\CC format manipulators are named, making them easier to read and remember. 3363 \item 3364 ©printf© separates format codes from associated variables, making it difficult to match codes with variables. 3365 \CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding. 3366 \item 3367 Format manipulators in \CC have global rather than local effect, except ©setw©. 3368 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects. 3369 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location. 3370 (To guarantee no side-effects, manipulator values must be saved and restored across function calls.) 3371 \end{itemize} 3372 The \CFA header file for the I/O library is \Indexc{fstream.hfa}. 3373 3374 For unformatted output, the common case is printing a sequence of variables separated by whitespace. 3348 \section{I/O Library} 3349 \label{s:IOLibrary} 3350 \index{input/output library} 3351 3352 The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 3353 The approach combines ideas from \CC and Python. 3354 The \CFA header file for the I/O library is \Indexc{fstream}. 3355 3356 The common case is printing out a sequence of variables separated by whitespace. 3375 3357 \begin{cquote} 3376 3358 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} … … 3391 3373 & 3392 3374 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3393 1 ® ®2® ®33375 1 2 3 3394 3376 \end{cfa} 3395 3377 \end{tabular} 3396 3378 \end{cquote} 3397 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators and newline.3398 Similar simplification occurs for \Index{tuple} I/O, which flattens the tuple and prints each valueseparated by ``\lstinline[showspaces=true]@, @''.3379 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators. 3380 Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''. 3399 3381 \begin{cfa} 3400 3382 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ]; 3401 sout | t1 | t2; §\C{// print tuples}§3383 sout | t1 | t2; §\C{// print tuples}§ 3402 3384 \end{cfa} 3403 3385 \begin{cfa}[showspaces=true,aboveskip=0pt] 3404 3386 1®, ®2®, ®3 4®, ®5®, ®6 3405 3387 \end{cfa} 3406 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable}operator, other than assignment.3388 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment. 3407 3389 Therefore, fewer output expressions require parenthesis. 3408 3390 \begin{cquote} … … 3411 3393 & 3412 3394 \begin{cfa} 3413 sout | x * 3 | y + 1 | z << 2 | x == y | ®(®x | y®)® | ®(®x || y®)® | ®(®x > z ? 1 : 2®)®;3395 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2); 3414 3396 \end{cfa} 3415 3397 \\ … … 3417 3399 & 3418 3400 \begin{cfa} 3419 cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << ®(®x | y®)® << ®(®x || y®)® << ®(®x > z ? 1 : 2®)®<< endl;3401 cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << (x | y) << (x || y) << (x > z ? 1 : 2) << endl; 3420 3402 \end{cfa} 3421 3403 \\ … … 3426 3408 \end{tabular} 3427 3409 \end{cquote} 3428 Input and output use a uniform operator, ©|©, rather than separate operators, as in ©>>© and ©<<© for \CC. 3429 There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output. 3430 3431 For unformatter input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable. 3432 \begin{cquote} 3433 \begin{lrbox}{\LstBox} 3434 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3435 int x; double y char z; 3436 \end{cfa} 3437 \end{lrbox} 3438 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 3439 \multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\ 3440 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 3441 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3442 sin | x | y | z; 3443 \end{cfa} 3444 & 3445 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3446 cin >> x >> y >> z; 3447 \end{cfa} 3448 \\ 3449 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3450 ®1® ®2.5® ®A® 3451 \end{cfa} 3452 & 3453 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3454 ®1® ®2.5® ®A® 3455 \end{cfa} 3456 \end{tabular} 3457 \end{cquote} 3458 3410 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. 3459 3411 3460 3412 3461 3413 \subsection{Implicit Separator} 3462 3414 3463 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator for output.3415 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator. 3464 3416 The rules for implicitly adding the separator are: 3465 3417 \begin{enumerate} … … 3489 3441 3490 3442 \item 3443 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@ 3444 %$ 3445 \begin{cfa}[mathescape=off] 3446 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" 3447 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10; 3448 \end{cfa} 3449 %$ 3450 \begin{cfa}[mathescape=off,basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt] 3451 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x ®$®5 x ®£®6 x ®¥®7 x ®¡®8 x ®¿®9 x ®«®10 3452 \end{cfa} 3453 %$ 3454 where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark. 3455 3456 \item 3491 3457 {\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}} 3492 A seperator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@3458 A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@ 3493 3459 \begin{cfa}[belowskip=0pt] 3494 3460 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" … … 3501 3467 3502 3468 \item 3503 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@ 3504 %$ 3505 \begin{cfa}[mathescape=off] 3506 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" 3507 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10; 3508 \end{cfa} 3509 %$ 3510 \begin{cfa}[mathescape=off,basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt] 3511 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x ®$®5 x ®£®6 x ®¥®7 x ®¡®8 x ®¿®9 x ®«®10 3512 \end{cfa} 3513 %$ 3514 where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark. 3515 3516 \item 3517 A seperator does not appear before/after a C string starting/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@ 3469 A seperator does not appear before or after a C string begining/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@ 3518 3470 \begin{cfa}[belowskip=0pt] 3519 3471 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx"; … … 3534 3486 3535 3487 3536 \subsection{Separation Manipulators} 3537 3538 The following \Index{manipulator}s control \Index{implicit output separation}. 3539 The effect of these manipulators is global for an output stream (except ©sepOn© and ©sepOff©). 3488 \subsection{Manipulator} 3489 3490 The following \CC-style \Index{manipulator}s and routines control implicit seperation. 3540 3491 \begin{enumerate} 3541 3492 \item 3542 \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.3493 Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string. 3543 3494 The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 3544 3495 \begin{cfa}[mathescape=off,belowskip=0pt] 3545 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§3496 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§ 3546 3497 sout | 1 | 2 | 3 | " \"" | ®sep® | "\""; 3547 3498 \end{cfa} … … 3552 3503 %$ 3553 3504 \begin{cfa}[belowskip=0pt] 3554 sepSet( sout, " " ); §\C{// reset separator to " "}§3505 sepSet( sout, " " ); §\C{// reset separator to " "}§ 3555 3506 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\""; 3556 3507 \end{cfa} … … 3560 3511 ©sepGet© can be used to store a separator and then restore it: 3561 3512 \begin{cfa}[belowskip=0pt] 3562 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§3563 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§3564 sepSet( sout, "_" ); §\C{// change separator to underscore}§3513 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§ 3514 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§ 3515 sepSet( sout, "_" ); §\C{// change separator to underscore}§ 3565 3516 sout | 1 | 2 | 3; 3566 3517 \end{cfa} … … 3569 3520 \end{cfa} 3570 3521 \begin{cfa}[belowskip=0pt] 3571 sepSet( sout, store ); §\C{// change separator back to original}§3522 sepSet( sout, store ); §\C{// change separator back to original}§ 3572 3523 sout | 1 | 2 | 3; 3573 3524 \end{cfa} … … 3577 3528 3578 3529 \item 3579 \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.3530 Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string. 3580 3531 The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 3581 3532 \begin{cfa}[belowskip=0pt] 3582 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§3533 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§ 3583 3534 sout | t1 | t2 | " \"" | ®sepTuple® | "\""; 3584 3535 \end{cfa} … … 3587 3538 \end{cfa} 3588 3539 \begin{cfa}[belowskip=0pt] 3589 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§3540 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§ 3590 3541 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\""; 3591 3542 \end{cfa} … … 3596 3547 3597 3548 \item 3598 \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} toggle printing the separator.3549 Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items. 3599 3550 \begin{cfa}[belowskip=0pt] 3600 sout | sepDisable | 1 | 2 | 3; §\C{//turn off implicit separator}§3551 sout | sepDisable | 1 | 2 | 3; §\C{// globally turn off implicit separator}§ 3601 3552 \end{cfa} 3602 3553 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3604 3555 \end{cfa} 3605 3556 \begin{cfa}[belowskip=0pt] 3606 sout | sepEnable | 1 | 2 | 3; §\C{//turn on implicit separator}§3557 sout | sepEnable | 1 | 2 | 3; §\C{// globally turn on implicit separator}§ 3607 3558 \end{cfa} 3608 3559 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3611 3562 3612 3563 \item 3613 \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} toggle printing the separator with respect to the next printed item, and then return to the global seperator setting.3564 Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item. 3614 3565 \begin{cfa}[belowskip=0pt] 3615 sout | 1 | sepOff | 2 | 3; §\C{// turn off implicit separator for the next item}§3566 sout | 1 | sepOff | 2 | 3; §\C{// locally turn off implicit separator}§ 3616 3567 \end{cfa} 3617 3568 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3619 3570 \end{cfa} 3620 3571 \begin{cfa}[belowskip=0pt] 3621 sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// turn on implicit separator for the next item}§3572 sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// locally turn on implicit separator}§ 3622 3573 \end{cfa} 3623 3574 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3626 3577 The tuple separator also responses to being turned on and off. 3627 3578 \begin{cfa}[belowskip=0pt] 3628 sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator}§3579 sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator}§ 3629 3580 \end{cfa} 3630 3581 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3634 3585 use ©sep© to accomplish this functionality. 3635 3586 \begin{cfa}[belowskip=0pt] 3636 sout | sepOn | 1 | 2 | 3 | sepOn; §\C{// sepOn does nothing at start/end of line}§3587 sout | sepOn | 1 | 2 | 3 | sepOn; §\C{// sepOn does nothing at start/end of line}§ 3637 3588 \end{cfa} 3638 3589 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 3640 3591 \end{cfa} 3641 3592 \begin{cfa}[belowskip=0pt] 3642 sout | sep | 1 | 2 | 3 | sep ; §\C{// use sep to print separator at start/end of line}§3593 sout | sep | 1 | 2 | 3 | sep ; §\C{// use sep to print separator at start/end of line}§ 3643 3594 \end{cfa} 3644 3595 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 3645 3596 ® ®1 2 3® ® 3646 \end{cfa}3647 \end{enumerate}3648 3649 3650 \subsection{Newline Manipulators}3651 3652 The following \Index{manipulator} controls \Index{newline separation} for input and output.3653 3654 For input:3655 \begin{enumerate}[parsep=0pt]3656 \item3657 \Indexc{nl}\index{manipulator!nl@©nl©} scans characters until the next newline character, i.e., ignore the remaining characters in the line.3658 \item3659 \Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} reads the newline character, when reading single characters.3660 \item3661 \Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} read the newline character, when reading single characters.3662 \end{enumerate}3663 For example, in:3664 \begin{cfa}3665 sin | i | ®nl® | j;3666 1 ®2®3667 33668 \end{cfa}3669 variable ©i© is assigned 1, the 2 is skipped, and variable ©j© is assigned 3.3670 3671 For output:3672 \begin{enumerate}[parsep=0pt]3673 \item3674 \Indexc{nl}\index{manipulator!nl@©nl©} inserts a newline.3675 \begin{cfa}3676 sout | nl; §\C{// only print newline}§3677 sout | 2; §\C{// implicit newline}§3678 sout | 3 | nl | 4 | nl; §\C{// terminating nl merged with implicit newline}§3679 sout | 5 | nl | nl; §\C{// again terminating nl merged with implicit newline}§3680 sout | 6; §\C{// implicit newline}§3681 3682 23683 33684 43685 53686 3687 63688 \end{cfa}3689 Note, a terminating ©nl© is merged (overrides) with the implicit newline at the end of the ©sout© expression, otherwise it is impossible to to print a single newline3690 \item3691 \Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} implicitly prints a newline at the end of each output expression.3692 \item3693 \Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} implicitly print a newline at the end of each output expression.3694 \end{enumerate}3695 3696 3697 \subsection{Output Value Manipulators}3698 3699 The following \Index{manipulator}s control formatting of output values (printing), and only affect the format of the argument.3700 \begin{enumerate}3701 \item3702 \Indexc{bin}( integer )\index{manipulator!bin@©bin©} print value in base 2 preceded by ©0b©/©0B©.3703 \begin{cfa}[belowskip=0pt]3704 sout | bin( 0 ) | bin( 27HH ) | bin( 27H ) | bin( 27 ) | bin( 27L );3705 0b0 0b11011 0b11011 0b11011 0b110113706 sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );3707 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)1001013708 \end{cfa}3709 3710 \item3711 \Indexc{oct}( integer )\index{manipulator!oct@©oct©} print value in base 8 preceded by ©0©.3712 \begin{cfa}[belowskip=0pt]3713 sout | oct( 0 ) | oct( 27HH ) | oct( 27H ) | oct( 27 ) | oct( 27L );3714 0 033 033 033 0333715 sout | oct( -27HH ) | oct( -27H ) | oct( -27 ) | oct( -27L );3716 0345 0177745 037777777745 017777777777777777777453717 \end{cfa}3718 Note, octal 0 is \emph{not} preceded by ©0© to prevent confusion.3719 3720 \item3721 \Indexc{hex}( integer / floating-point )\index{manipulator!hex@©hex©} print value in base 16 preceded by ©0x©/©0X©.3722 \begin{cfa}[belowskip=0pt]3723 sout | hex( 0 ) | hex( 27HH ) | hex( 27H ) | hex( 27 ) | hex( 27L );3724 0 0x1b 0x1b 0x1b 0x1b3725 sout | hex( -27HH ) | hex( -27H ) | hex( -27 ) | hex( -27L );3726 0xe5 0xffe5 0xffffffe5 0xffffffffffffffe53727 3728 sout | hex( 0.0 ) | hex( 27.5F ) | hex( 27.5 ) | hex( 27.5L );3729 0x0.p+0 0x1.b8p+4 0x1.b8p+4 0xd.cp+13730 sout | hex( -27.5F ) | hex( -27.5 ) | hex( -27.5L );3731 -0x1.b8p+4 -0x1.b8p+4 -0xd.cp+13732 \end{cfa}3733 3734 \item3735 \Indexc{sci}( floating-point )\index{manipulator!sci@©sci©} print value in scientific notation with exponent.3736 Default is 6 digits of precision.3737 \begin{cfa}[belowskip=0pt]3738 sout | sci( 0.0 ) | sci( 27.5 ) | sci( -27.5 );3739 0.000000e+00 2.750000e+01 -2.750000e+013740 \end{cfa}3741 3742 \item3743 \Indexc{upcase}( bin / hex / floating-point )\index{manipulator!upcase@©upcase©} print letters in a value in upper case. Lower case is the default.3744 \begin{cfa}[belowskip=0pt]3745 sout | upcase( bin( 27 ) ) | upcase( hex( 27 ) ) | upcase( 27.5e-10 ) | upcase( hex( 27.5 ) );3746 0®B®11011 0®X®1®B® 2.75®E®-09 0®X®1.®B®8®P®+43747 \end{cfa}3748 3749 \item3750 \Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©. Printing the base is the default.3751 \begin{cfa}[belowskip=0pt]3752 sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) );3753 11011 33 1b3754 \end{cfa}3755 3756 \item3757 \Indexc{nodp}( floating-point )\index{manipulator!nodp@©nodp©} do not print a decimal point if there are no fractional digits.3758 Printing a decimal point is the default, if there are no fractional digits.3759 \begin{cfa}[belowskip=0pt]3760 sout | 0. | nodp( 0. ) | 27.0 | nodp( 27.0 ) | nodp( 27.5 );3761 0.0 ®0® 27.0 ®27® 27.53762 \end{cfa}3763 3764 \item3765 \Indexc{sign}( integer / floating-point )\index{manipulator!sign@©sign©} prefix with plus or minus sign (©+© or ©-©). Only printing the minus sign is the default.3766 \begin{cfa}[belowskip=0pt]3767 sout | sign( 27 ) | sign( -27 ) | sign( 27. ) | sign( -27. ) | sign( 27.5 ) | sign( -27.5 );3768 ®+®27 -27 ®+®27.0 -27.0 ®+®27.5 -27.53769 \end{cfa}3770 3771 \item3772 \Indexc{wd}©( unsigned char minimum, T val )©\index{manipulator!wd@©wd©}, ©wd( unsigned char minimum, unsigned char precision, T val )©3773 For all types, ©minimum© is the minimum number of printed characters.3774 If the value is shorter than the minimum, it is padded on the right with spaces.3775 \begin{cfa}[belowskip=0pt]3776 sout | wd( 4, 34) | wd( 3, 34 ) | wd( 2, 34 );3777 sout | wd( 10, 4.) | wd( 9, 4. ) | wd( 8, 4. );3778 sout | wd( 4, "ab" ) | wd( 3, "ab" ) | wd( 2, "ab" );3779 \end{cfa}3780 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3781 ® ®34 ® ®34 343782 ® ®4.000000 ® ®4.000000 4.0000003783 ® ®ab ® ®ab ab3784 ab ab ab3785 \end{cfa}3786 If the value is larger, it is printed without truncation, ignoring the ©minimum©.3787 \begin{cfa}[belowskip=0pt]3788 sout | wd( 4, 34567 ) | wd( 3, 34567 ) | wd( 2, 34567 );3789 sout | wd( 4, 3456. ) | wd( 3, 3456. ) | wd( 2, 3456. );3790 sout | wd( 4, "abcde" ) | wd( 3, "abcde" ) | wd( 2,"abcde" );3791 \end{cfa}3792 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3793 3456®7® 345®67® 34®567®3794 3456®.® 345®6.® 34®56.®3795 abcd®e® abc®de® ab®cde®3796 \end{cfa}3797 3798 For integer types, ©precision© is the minimum number of printed digits.3799 If the value is shorter, it is padded on the left with leading zeros.3800 \begin{cfa}[belowskip=0pt]3801 sout | wd( 4,3, 34 ) | wd( 8,4, 34 ) | wd( 10,10, 34 );3802 \end{cfa}3803 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3804 ®0®34 ®00®34 ®00000000®343805 \end{cfa}3806 If the value is larger, it is printed without truncation, ignoring the ©precision©.3807 \begin{cfa}[belowskip=0pt]3808 sout | wd( 4,1, 3456 ) | wd( 8,2, 3456 ) | wd( 10,3, 3456 );3809 \end{cfa}3810 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3811 3456 3456 34563812 \end{cfa}3813 If ©precision© is 0, nothing is printed for zero.3814 If ©precision© is greater than the minimum, it becomes the minimum.3815 \begin{cfa}[belowskip=0pt]3816 sout | wd( 4,0, 0 ) | wd( 3,10, 34 );3817 \end{cfa}3818 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3819 ® ® ®00000000®343820 \end{cfa}3821 For floating-point types, ©precision© is the minimum number of digits after the decimal point.3822 \begin{cfa}[belowskip=0pt]3823 sout | wd( 6,3, 27.5 ) | wd( 8,1, 27.5 ) | wd( 8,0, 27.5 ) | wd( 3,8, 27.5 );3824 \end{cfa}3825 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3826 27.®500® 27.®5® 28. 27.®50000000®3827 \end{cfa}3828 For the C-string type, ©precision© is the maximum number of printed characters, so the string is truncared if it exceeds the maximum.3829 \begin{cfa}[belowskip=0pt]3830 sout | wd( 6,8, "abcd" ) | wd( 6,8, "abcdefghijk" ) | wd( 6,3, "abcd" );3831 \end{cfa}3832 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3833 abcd abcdefgh abc3834 \end{cfa}3835 3836 \item3837 \Indexc{ws( unsigned char minimum, unsigned char significant, floating-point )}\index{manipulator!ws@©ws©}3838 For floating-point type, ©minimum© is the same as for manipulator ©wd©, but ©significant© is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for ©wd©).3839 If a value's significant digits is greater than ©significant©, the last significant digit is rounded up.3840 \begin{cfa}[belowskip=0pt]3841 sout | ws(6,6, 234.567) | ws(6,5, 234.567) | ws(6,4, 234.567) | ws(6,3, 234.567);3842 \end{cfa}3843 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3844 234.567 234.5®7® 234.®6® 23®5®3845 \end{cfa}3846 If a value's magnitude is greater than ©significant©, the value is printed in scientific notation with the specified number of significant digits.3847 \begin{cfa}[belowskip=0pt]3848 sout | ws(6,6, 234567.) | ws(6,5, 234567.) | ws(6,4, 234567.) | ws(6,3, 234567.);3849 \end{cfa}3850 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3851 234567. 2.3457®e+05® 2.346®e+05® 2.35®e+05®3852 \end{cfa}3853 If ©significant© is greater than ©minimum©, it defines the number of printed characters.3854 \begin{cfa}[belowskip=0pt]3855 sout | ws(3,6, 234567.) | ws(4,6, 234567.) | ws(5,6, 234567.) | ws(6,6, 234567.);3856 \end{cfa}3857 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3858 234567. 234567. 234567. 234567.3859 \end{cfa}3860 3861 \item3862 \Indexc{left}( field-width )\index{manipulator!left@©left©} left justify within the given field.3863 \begin{cfa}[belowskip=0pt]3864 sout | left(wd(4, 27)) | left(wd(10, 27.)) | left(wd(10, 27.5)) | left(wd(4,3, 27)) | left(wd(10,3, 27.5));3865 \end{cfa}3866 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3867 27® ® 27.000000 27.500000 027 27.500® ®3868 \end{cfa}3869 3870 \item3871 \Indexc{pad0}( field-width )\index{manipulator!pad0@©pad0©} left pad with zeroes (0).3872 \begin{cfa}[belowskip=0pt]3873 sout | pad0( wd( 4, 27 ) ) | pad0( wd( 4,3, 27 ) ) | pad0( wd( 8,3, 27.5 ) );3874 ®00®27 ®0®27 ®00®27.5003875 3597 \end{cfa} 3876 3598 \end{enumerate} … … 3933 3655 3934 3656 3935 \subsection{Input Value Manipulators}3936 3937 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable.3938 For ©_Bool© type, the constants are ©true© and ©false©.3939 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a3940 \begin{itemize}3941 \item3942 ©1©-©9© prefix introduces a decimal value (©0©-©9©),3943 \item3944 ©0© prefix introduces an octal value (©0©-©7©), and3945 \item3946 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters.3947 \end{itemize}3948 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits.3949 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©.3950 3951 For the C-string type, the input values are \emph{not} the same as C-string constants, \ie double quotes bracketing arbitrary text with escape sequences.3952 Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter ©'\0'©.3953 The string variable \emph{must} be large enough to contain the input sequence.3954 3955 The following \Index{manipulator}s control formatting of input values (reading), and only affect the format of the argument.3956 3957 \begin{enumerate}3958 \item3959 \Indexc{skip( const char * pattern )}\index{manipulator!skip@©skip©} / ©skip( unsigned int length )© / ©const char * pattern©3960 The argument defines a ©pattern© or ©length©.3961 The ©pattern© is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character.3962 The ©length© is composed of the next $N$ characters, including the newline character.3963 If the match successes, the input characters are discarded, and input continues with the next character.3964 If the match fails, the input characters are left unread.3965 \begin{cfa}[belowskip=0pt]3966 char sk[$\,$] = "abc";3967 sin | "abc " | skip( sk ) | skip( 5 ); // match input sequence3968 \end{cfa}3969 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3970 ®abc ®3971 ®abc ®3972 ®xx®3973 \end{cfa}3974 3975 \item3976 \Indexc{wdi}©( unsigned int maximum, T & val )©\index{manipulator!wdi@©wdi©}3977 For all types except ©char©, ©maximum© is the maximum number of characters read for the current operation.3978 \begin{cfa}[belowskip=0pt]3979 char s[10]; int i; double d;3980 sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d ); // c == "abcd", i == 123, d == 3.456E+23981 \end{cfa}3982 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3983 ®abcd1233.456E+2®3984 \end{cfa}3985 Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types.3986 Currently, \CFA cannot distinguish between these two manipulators in the middle of an ©sout©/©sin© expression based on return type.3987 3988 \item3989 \Indexc{ignore( T & val )}\index{manipulator!ignore@©ignore©}3990 For all types, the data is read from the stream depending on the argument type but ignored, \ie it is not stored in the argument.3991 \begin{cfa}[belowskip=0pt]3992 double d;3993 sin | ignore( d ); // d is unchanged3994 \end{cfa}3995 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]3996 ® -75.35e-4® 253997 \end{cfa}3998 3999 \item4000 \Indexc{incl( const char * scanset, char * s )}\index{manipulator!incl@©incl©}4001 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{in} the set.4002 Matching characters are read into the C string and null terminated.4003 \begin{cfa}[belowskip=0pt]4004 char s[10];4005 sin | incl( "abc", s );4006 \end{cfa}4007 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]4008 ®bca®xyz4009 \end{cfa}4010 4011 \item4012 \Indexc{excl( const char * scanset, char * s )}\index{manipulator!excl@©excl©}4013 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{not in} the set.4014 Non-matching characters are read into the C string and null terminated.4015 \begin{cfa}[belowskip=0pt]4016 char s[10];4017 sin | excl( "abc", s );4018 \end{cfa}4019 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]4020 ®xyz®bca4021 \end{cfa}4022 \end{enumerate}4023 4024 4025 3657 \section{Types} 4026 3658 … … 4390 4022 \begin{itemize} 4391 4023 \item 4392 not determining or writinglong generic types,4393 \item 4394 ensur ingsecondary variables, related to a primary variable, always have the same type.4024 preventing having to determine or write long generic types, 4025 \item 4026 ensure secondary variables, related to a primary variable, always have the same type. 4395 4027 \end{itemize} 4396 4028 … … 4414 4046 There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type. 4415 4047 That is, when is the type of the variable more important than the type of its initialization expression. 4416 For example, if a change is made in an initialization expression, it can cause cascading type changes and/or errors.4048 For example, if a change is made in an initialization expression, it can cause significant cascading type changes and/or errors. 4417 4049 At some point, a variable type needs to remain constant and the expression to be in error when it changes. 4418 4050 … … 4647 4279 4648 4280 coroutine Fibonacci { 4649 int fn; §\C{// used for communication}§4281 int fn; §\C{// used for communication}§ 4650 4282 }; 4651 4283 void ?{}( Fibonacci * this ) { … … 4653 4285 } 4654 4286 void main( Fibonacci * this ) { 4655 int fn1, fn2; §\C{// retained between resumes}§4656 this->fn = 0; §\C{// case 0}§4287 int fn1, fn2; §\C{// retained between resumes}§ 4288 this->fn = 0; §\C{// case 0}§ 4657 4289 fn1 = this->fn; 4658 suspend(); §\C{// return to last resume}§4659 4660 this->fn = 1; §\C{// case 1}§4290 suspend(); §\C{// return to last resume}§ 4291 4292 this->fn = 1; §\C{// case 1}§ 4661 4293 fn2 = fn1; 4662 4294 fn1 = this->fn; 4663 suspend(); §\C{// return to last resume}§4664 4665 for ( ;; ) { §\C{// general case}§4295 suspend(); §\C{// return to last resume}§ 4296 4297 for ( ;; ) { §\C{// general case}§ 4666 4298 this->fn = fn1 + fn2; 4667 4299 fn2 = fn1; 4668 4300 fn1 = this->fn; 4669 suspend(); §\C{// return to last resume}§4301 suspend(); §\C{// return to last resume}§ 4670 4302 } // for 4671 4303 } 4672 4304 int next( Fibonacci * this ) { 4673 resume( this ); §\C{// transfer to last suspend}§4305 resume( this ); §\C{// transfer to last suspend}§ 4674 4306 return this->fn; 4675 4307 } … … 6216 5848 In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as: 6217 5849 \begin{cfa} 6218 *?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§6219 *§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§5850 *?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§ 5851 *§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§ 6220 5852 \end{cfa} 6221 5853 By default, the first interpretation is selected, which does not yield a meaningful parse. … … 6269 5901 \eg: 6270 5902 \begin{cfa} 6271 x; §\C{// int x}§6272 *y; §\C{// int *y}§6273 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§6274 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§5903 x; §\C{// int x}§ 5904 *y; §\C{// int *y}§ 5905 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 5906 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 6275 5907 \end{cfa} 6276 5908 \CFA continues to support K\&R routine definitions: 6277 5909 \begin{cfa} 6278 f( a, b, c ) §\C{// default int return}§6279 int a, b; char c §\C{// K\&R parameter declarations}§5910 f( a, b, c ) §\C{// default int return}§ 5911 int a, b; char c §\C{// K\&R parameter declarations}§ 6280 5912 { 6281 5913 ... … … 6296 5928 int rtn( int i ); 6297 5929 int rtn( char c ); 6298 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§5930 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 6299 5931 \end{cfa} 6300 5932 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. … … 6318 5950 \item[Change:] make string literals ©const©: 6319 5951 \begin{cfa} 6320 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§6321 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§5952 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 5953 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 6322 5954 \end{cfa} 6323 5955 The type of a string literal is changed from ©[] char© to ©const [] char©. … … 6326 5958 \begin{cfa} 6327 5959 char * p = "abc"; 6328 p[0] = 'w'; §\C{// segment fault or change constant literal}§5960 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 6329 5961 \end{cfa} 6330 5962 The same problem occurs when passing a string literal to a routine that changes its argument. … … 6338 5970 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 6339 5971 \begin{cfa} 6340 int i; §\C{// forward definition}§6341 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§6342 int i = 0; §\C{// definition}§5972 int i; §\C{// forward definition}§ 5973 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 5974 int i = 0; §\C{// definition}§ 6343 5975 \end{cfa} 6344 5976 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. … … 6346 5978 \begin{cfa} 6347 5979 struct X { int i; struct X *next; }; 6348 static struct X a; §\C{// forward definition}§5980 static struct X a; §\C{// forward definition}§ 6349 5981 static struct X b = { 0, ®&a® };§\C{// forward reference, valid in C, invalid in \CFA}§ 6350 static struct X a = { 1, &b }; §\C{// definition}§5982 static struct X a = { 1, &b }; §\C{// definition}§ 6351 5983 \end{cfa} 6352 5984 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types. … … 6363 5995 struct Person { 6364 5996 enum ®Colour® { R, G, B }; §\C[7cm]{// nested type}§ 6365 struct Face { §\C{// nested type}§6366 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§5997 struct Face { §\C{// nested type}§ 5998 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 6367 5999 }; 6368 ®.Colour® shirt; §\C{// type defined outside (top level)}§6369 ®Colour® pants; §\C{// type defined same level}§6370 Face looks[10]; §\C{// type defined same level}§6000 ®.Colour® shirt; §\C{// type defined outside (top level)}§ 6001 ®Colour® pants; §\C{// type defined same level}§ 6002 Face looks[10]; §\C{// type defined same level}§ 6371 6003 }; 6372 ®Colour® c = R; §\C{// type/enum defined same level}§6004 ®Colour® c = R; §\C{// type/enum defined same level}§ 6373 6005 Person®.Colour® pc = Person®.®R;§\C{// type/enum defined inside}§ 6374 Person®.®Face pretty; §\C{// type defined inside}\CRT§6006 Person®.®Face pretty; §\C{// type defined inside}\CRT§ 6375 6007 \end{cfa} 6376 6008 In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing. … … 6389 6021 \item[Difficulty of converting:] Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example: 6390 6022 \begin{cfa} 6391 struct Y; §\C{// struct Y and struct X are at the same scope}§6023 struct Y; §\C{// struct Y and struct X are at the same scope}§ 6392 6024 struct X { 6393 6025 struct Y { /* ... */ } y; … … 6404 6036 \begin{cfa} 6405 6037 void foo() { 6406 int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§6407 char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§6038 int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§ 6039 char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§ 6408 6040 } 6409 6041 \end{cfa} … … 6666 6298 \leavevmode 6667 6299 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 6668 forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§6300 forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§ 6669 6301 T * bsearch( T key, const T * arr, size_t dim );§\indexc{bsearch}§ 6670 6302 6671 forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§6303 forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§ 6672 6304 unsigned int bsearch( T key, const T * arr, size_t dim ); 6673 6305 … … 6676 6308 6677 6309 forall( otype E | { int ?<?( E, E ); } ) { 6678 E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§ §\C{// location}§6310 E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§ §\C{// location}§ 6679 6311 size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§ 6680 6312 E * bsearchl( E key, const E * vals, size_t dim );§\indexc{bsearchl}§ … … 6724 6356 void srandom( unsigned int seed );§\indexc{srandom}§ 6725 6357 char random( void );§\indexc{random}§ 6726 char random( char u ); §\C{// [0,u)}§6727 char random( char l, char u ); §\C{// [l,u)}§6358 char random( char u ); §\C{// [0,u)}§ 6359 char random( char l, char u ); §\C{// [l,u)}§ 6728 6360 int random( void ); 6729 int random( int u ); §\C{// [0,u)}§6730 int random( int l, int u ); §\C{// [l,u)}§6361 int random( int u ); §\C{// [0,u)}§ 6362 int random( int l, int u ); §\C{// [l,u)}§ 6731 6363 unsigned int random( void ); 6732 unsigned int random( unsigned int u ); §\C{// [0,u)}§6364 unsigned int random( unsigned int u ); §\C{// [0,u)}§ 6733 6365 unsigned int random( unsigned int l, unsigned int u ); §\C{// [l,u)}§ 6734 6366 long int random( void ); 6735 long int random( long int u ); §\C{// [0,u)}§6736 long int random( long int l, long int u ); §\C{// [l,u)}§6367 long int random( long int u ); §\C{// [0,u)}§ 6368 long int random( long int l, long int u ); §\C{// [l,u)}§ 6737 6369 unsigned long int random( void ); 6738 6370 unsigned long int random( unsigned long int u ); §\C{// [0,u)}§ … … 6785 6417 [ int, long double ] remquo( long double, long double ); 6786 6418 6787 float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§6419 float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§ 6788 6420 double div( double, double, int * ); 6789 6421 long double div( long double, long double, int * ); … … 6941 6573 long double atan2( long double, long double ); 6942 6574 6943 float atan( float, float ); §\C{// alternative name for atan2}§6575 float atan( float, float ); §\C{// alternative name for atan2}§ 6944 6576 double atan( double, double );§\indexc{atan}§ 6945 6577 long double atan( long double, long double ); … … 7132 6764 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7133 6765 struct Duration { 7134 int64_t tv; §\C{// nanoseconds}§6766 int64_t tv; §\C{// nanoseconds}§ 7135 6767 }; 7136 6768 … … 7262 6894 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7263 6895 struct Time { 7264 uint64_t tv; §\C{// nanoseconds since UNIX epoch}§6896 uint64_t tv; §\C{// nanoseconds since UNIX epoch}§ 7265 6897 }; 7266 6898 … … 7333 6965 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7334 6966 struct Clock { 7335 Duration offset; §\C{// for virtual clock: contains offset from real-time}§7336 int clocktype; §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§6967 Duration offset; §\C{// for virtual clock: contains offset from real-time}§ 6968 int clocktype; §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§ 7337 6969 }; 7338 6970 … … 7342 6974 void ?{}( Clock & clk, Duration adj ); 7343 6975 7344 Duration getResNsec(); §\C{// with nanoseconds}§7345 Duration getRes(); §\C{// without nanoseconds}§7346 7347 Time getTimeNsec(); §\C{// with nanoseconds}§7348 Time getTime(); §\C{// without nanoseconds}§6976 Duration getResNsec(); §\C{// with nanoseconds}§ 6977 Duration getRes(); §\C{// without nanoseconds}§ 6978 6979 Time getTimeNsec(); §\C{// with nanoseconds}§ 6980 Time getTime(); §\C{// without nanoseconds}§ 7349 6981 Time getTime( Clock & clk ); 7350 6982 Time ?()( Clock & clk ); … … 7362 6994 7363 6995 \begin{cfa} 7364 void ?{}( Int * this ); §\C{// constructor/destructor}§6996 void ?{}( Int * this ); §\C{// constructor/destructor}§ 7365 6997 void ?{}( Int * this, Int init ); 7366 6998 void ?{}( Int * this, zero_t ); … … 7371 7003 void ^?{}( Int * this ); 7372 7004 7373 Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§7005 Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§ 7374 7006 Int ?=?( Int * lhs, long int rhs ); 7375 7007 Int ?=?( Int * lhs, unsigned long int rhs ); … … 7388 7020 unsigned long int narrow( Int val ); 7389 7021 7390 int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§7022 int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§ 7391 7023 int ?==?( Int oper1, long int oper2 ); 7392 7024 int ?==?( long int oper2, Int oper1 ); … … 7424 7056 int ?>=?( unsigned long int oper1, Int oper2 ); 7425 7057 7426 Int +?( Int oper ); §\C{// arithmetic}§7058 Int +?( Int oper ); §\C{// arithmetic}§ 7427 7059 Int -?( Int oper ); 7428 7060 Int ~?( Int oper ); … … 7506 7138 Int ?>>=?( Int * lhs, mp_bitcnt_t shift ); 7507 7139 7508 Int abs( Int oper ); §\C{// number functions}§7140 Int abs( Int oper ); §\C{// number functions}§ 7509 7141 Int fact( unsigned long int N ); 7510 7142 Int gcd( Int oper1, Int oper2 ); … … 7617 7249 // implementation 7618 7250 struct Rational {§\indexc{Rational}§ 7619 long int numerator, denominator; §\C{// invariant: denominator > 0}§7251 long int numerator, denominator; §\C{// invariant: denominator > 0}§ 7620 7252 }; // Rational 7621 7253 7622 Rational rational(); §\C{// constructors}§7254 Rational rational(); §\C{// constructors}§ 7623 7255 Rational rational( long int n ); 7624 7256 Rational rational( long int n, long int d ); … … 7626 7258 void ?{}( Rational * r, one_t ); 7627 7259 7628 long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§7260 long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§ 7629 7261 long int numerator( Rational r, long int n ); 7630 7262 long int denominator( Rational r ); 7631 7263 long int denominator( Rational r, long int d ); 7632 7264 7633 int ?==?( Rational l, Rational r ); §\C{// comparison}§7265 int ?==?( Rational l, Rational r ); §\C{// comparison}§ 7634 7266 int ?!=?( Rational l, Rational r ); 7635 7267 int ?<?( Rational l, Rational r ); … … 7638 7270 int ?>=?( Rational l, Rational r ); 7639 7271 7640 Rational -?( Rational r ); §\C{// arithmetic}§7272 Rational -?( Rational r ); §\C{// arithmetic}§ 7641 7273 Rational ?+?( Rational l, Rational r ); 7642 7274 Rational ?-?( Rational l, Rational r ); … … 7644 7276 Rational ?/?( Rational l, Rational r ); 7645 7277 7646 double widen( Rational r ); §\C{// conversion}§7278 double widen( Rational r ); §\C{// conversion}§ 7647 7279 Rational narrow( double f, long int md ); 7648 7280
Note:
See TracChangeset
for help on using the changeset viewer.