Changeset f988834 for doc/user/user.tex
- Timestamp:
- Jan 19, 2024, 2:44:41 AM (20 months ago)
- Branches:
- master
- Children:
- ac939461
- Parents:
- 59c8dff (diff), e8b3717 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
r59c8dff rf988834 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 Sep 30 22:46:19 202314 %% Update Count : 5 65813 %% Last Modified On : Sun Jan 14 17:27:41 2024 14 %% Update Count : 5764 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 55 55 \SetWatermarkLightness{0.9} 56 56 57 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore 58 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR 59 % AFTER HYPERREF. 60 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 57 % Default underscore is too low. Cannot use lstlisting "literate" as replacing underscore removes it 58 % as a variable-name character so keywords in variables are highlighted. MUST APPEAR AFTER HYPERREF. 59 \renewcommand{\textunderscore}{\makebox[1.4ex][c]{{\raisebox{1.25pt}{\char`\_}}}} 61 60 62 61 \setlength{\topmargin}{-0.45in} % move running title into header … … 67 66 \CFAStyle % use default CFA format-style 68 67 \setgcolumn{2.25in} 69 %\lstset{language=CFA} % CFA default lnaguage68 \lstset{language=CFA} % CFA default lnaguage 70 69 \lstnewenvironment{C++}[1][] % use C++ style 71 70 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®},#1}} … … 172 171 \begin{tabular}{@{}lll@{}} 173 172 \multicolumn{1}{@{}c}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{\CC}} \\ 174 \begin{cfa} [tabsize=3]175 #include <stdio.h> $\indexc{stdio.h}$173 \begin{cfa} 174 #include <stdio.h>§\indexc{stdio.h}§ 176 175 177 176 int main( void ) { … … 182 181 & 183 182 \begin{cfa}[tabsize=3] 184 #include <fstream> $\indexc{fstream}$183 #include <fstream>§\indexc{fstream}§ 185 184 186 185 int main( void ) { 187 186 int x = 0, y = 1, z = 2; 188 ®sout | x | y | z;® $\indexc{sout}$187 ®sout | x | y | z;®§\indexc{sout}§ 189 188 } 190 189 \end{cfa} 191 190 & 192 191 \begin{cfa}[tabsize=3] 193 #include <iostream> $\indexc{iostream}$192 #include <iostream>§\indexc{iostream}§ 194 193 using namespace std; 195 194 int main() { … … 260 259 \begin{cfa} 261 260 ®forall( T )® T identity( T val ) { return val; } 262 int forty_two = identity( 42 ); $\C{// T is bound to int, forty\_two == 42}$261 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§ 263 262 \end{cfa} 264 263 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. … … 288 287 289 288 double key = 5.0, vals[10] = { /* 10 sorted floating values */ }; 290 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); $\C{// search sorted array}$289 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§ 291 290 \end{cfa} 292 291 which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers: … … 297 296 298 297 forall( T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) { 299 T * result = bsearch( key, arr, size ); $\C{// call first version}$300 return result ? result - arr : size; } $\C{// pointer subtraction includes sizeof(T)}$301 302 double * val = bsearch( 5.0, vals, 10 ); $\C{// selection based on return type}$298 T * result = bsearch( key, arr, size ); §\C{// call first version}§ 299 return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§ 300 301 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§ 303 302 int posn = bsearch( 5.0, vals, 10 ); 304 303 \end{cfa} … … 312 311 \begin{cfa} 313 312 forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 314 int * ip = malloc(); $\C{// select type and size from left-hand side}$313 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 315 314 double * dp = malloc(); 316 315 struct S {...} * sp = malloc(); … … 324 323 \begin{cfa} 325 324 char ®abs®( char ); 326 extern "C" { int ®abs®( int ); } $\C{// use default C routine for int}$325 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§ 327 326 long int ®abs®( long int ); 328 327 long long int ®abs®( long long int ); … … 349 348 The command ©cfa© is used to compile a \CFA program and is based on the \Index{GNU} \Indexc{gcc} command, \eg: 350 349 \begin{cfa} 351 cfa $\indexc{cfa}\index{compilation!cfa@©cfa©}$ [ gcc/$\CFA{}$-options ] [ C/$\CFA{}$source-files ] [ assembler/loader files ]350 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc/§\CFA{}§-options ] [ C/§\CFA{}§ source-files ] [ assembler/loader files ] 352 351 \end{cfa} 353 352 There is no ordering among options (flags) and files, unless an option has an argument, which must appear immediately after the option possibly with or without a space separating option and argument. … … 438 437 \begin{cfa} 439 438 #ifndef __CFORALL__ 440 #include <stdio.h> $\indexc{stdio.h}$ $\C{// C header file}$439 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§ 441 440 #else 442 #include <fstream> $\indexc{fstream}$ $\C{// \CFA header file}$441 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§ 443 442 #endif 444 443 \end{cfa} … … 450 449 Each option must be escaped with \Indexc{-XCFA}\index{translator option!-XCFA@{©-XCFA©}} to direct it to the compiler step, similar to the ©-Xlinker© flag for the linker, \eg: 451 450 \begin{lstlisting}[language=sh] 452 cfa $test$.cfa -CFA -XCFA -p # print translated code without printing the standard prelude453 cfa $test$.cfa -XCFA -P -XCFA parse -XCFA -n # show program parse without prelude451 cfa §test§.cfa -CFA -XCFA -p # print translated code without printing the standard prelude 452 cfa §test§.cfa -XCFA -P -XCFA parse -XCFA -n # show program parse without prelude 454 453 \end{lstlisting} 455 Alternatively, multiple flag es can be specified separated with commas and \emph{without} spaces.454 Alternatively, multiple flags can be specified separated with commas and \emph{without} spaces. 456 455 \begin{lstlisting}[language=sh,{moredelim=**[is][\protect\color{red}]{®}{®}}] 457 cfa $test$.cfa -XCFA®,®-Pparse®,®-n # show program parse without prelude456 cfa §test§.cfa -XCFA®,®-Pparse®,®-n # show program parse without prelude 458 457 \end{lstlisting} 459 458 \begin{description}[topsep=5pt,itemsep=0pt,parsep=0pt] … … 537 536 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 538 537 \begin{cfa} 539 int ®``®coroutine = 3; $\C{// make keyword an identifier}$538 int ®``®coroutine = 3; §\C{// make keyword an identifier}§ 540 539 double ®``®forall = 3.5; 541 540 \end{cfa} … … 547 546 \begin{cfa} 548 547 // include file uses the CFA keyword "with". 549 #if ! defined( with ) $\C{// nesting ?}$550 #define with ®``®with $\C{// make keyword an identifier}$548 #if ! defined( with ) §\C{// nesting ?}§ 549 #define with ®``®with §\C{// make keyword an identifier}§ 551 550 #define __CFA_BFD_H__ 552 551 #endif 553 $\R{\#include\_next} <bfdlink.h>$ $\C{// must have internal check for multiple expansion}$ 554 #if defined( with ) && defined( __CFA_BFD_H__ ) $\C{// reset only if set}$552 §\R{\#include\_next} <bfdlink.h>§ §\C{// must have internal check for multiple expansion}§ 553 #if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§ 555 554 #undef with 556 555 #undef __CFA_BFD_H__ … … 566 565 Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore} as a separator, \eg: 567 566 \begin{cfa} 568 2®_®147®_®483®_®648; $\C{// decimal constant}$569 56®_®ul; $\C{// decimal unsigned long constant}$570 0®_®377; $\C{// octal constant}$571 0x®_®ff®_®ff; $\C{// hexadecimal constant}$572 0x®_®ef3d®_®aa5c; $\C{// hexadecimal constant}$573 3.141®_®592®_®654; $\C{// floating constant}$574 10®_®e®_®+1®_®00; $\C{// floating constant}$575 0x®_®ff®_®ff®_®p®_®3; $\C{// hexadecimal floating}$576 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; $\C{// hexadecimal floating long constant}$577 L®_® $"\texttt{\textbackslash{x}}$®_®$\texttt{ff}$®_®$\texttt{ee}"$; $\C{// wide character constant}$567 2®_®147®_®483®_®648; §\C{// decimal constant}§ 568 56®_®ul; §\C{// decimal unsigned long constant}§ 569 0®_®377; §\C{// octal constant}§ 570 0x®_®ff®_®ff; §\C{// hexadecimal constant}§ 571 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§ 572 3.141®_®592®_®654; §\C{// floating constant}§ 573 10®_®e®_®+1®_®00; §\C{// floating constant}§ 574 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§ 575 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§ 576 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 578 577 \end{cfa} 579 578 The rules for placement of underscores are: … … 635 634 Declarations in the \Indexc{do}-©while© condition are not useful because they appear after the loop body.} 636 635 \begin{cfa} 637 if ( ®int x = f()® ) ... $\C{// x != 0}$638 if ( ®int x = f(), y = g()® ) ... $\C{// x != 0 \&\& y != 0}$639 if ( ®int x = f(), y = g(); x < y® ) ... $\C{// relational expression}$640 if ( ®struct S { int i; } x = { f() }; x.i < 4® ) $\C{// relational expression}$641 642 while ( ®int x = f()® ) ... $\C{// x != 0}$643 while ( ®int x = f(), y = g()® ) ... $\C{// x != 0 \&\& y != 0}$644 while ( ®int x = f(), y = g(); x < y® ) ... $\C{// relational expression}$645 while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... $\C{// relational expression}$636 if ( ®int x = f()® ) ... §\C{// x != 0}§ 637 if ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§ 638 if ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§ 639 if ( ®struct S { int i; } x = { f() }; x.i < 4® ) §\C{// relational expression}§ 640 641 while ( ®int x = f()® ) ... §\C{// x != 0}§ 642 while ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§ 643 while ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§ 644 while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... §\C{// relational expression}§ 646 645 \end{cfa} 647 646 Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the ©if©/©while© expression, and the results are combined using the logical \Indexc{&&} operator. … … 713 712 \begin{cfa} 714 713 switch ( i ) { 715 case 1 $\R{\textvisiblespace}$®...®4:714 case 1§\R{\textvisiblespace}§®...®4: 716 715 ... 717 case 10 $\R{\textvisiblespace}$®...®13:716 case 10§\R{\textvisiblespace}§®...®13: 718 717 ... 719 718 } … … 752 751 case 1: 753 752 ... 754 $\R{\LstCommentStyle{// fall-through}}$753 §\R{\LstCommentStyle{// fall-through}}§ 755 754 case 2: 756 755 ... … … 853 852 \begin{cfa} 854 853 switch ( x ) { 855 ®int y = 1;® $\C{// unreachable initialization}$856 ®x = 7;® $\C{// unreachable code without label/branch}$854 ®int y = 1;® §\C{// unreachable initialization}§ 855 ®x = 7;® §\C{// unreachable code without label/branch}§ 857 856 case 0: ... 858 857 ... 859 ®int z = 0;® $\C{// unreachable initialization, cannot appear after case}$858 ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§ 860 859 z = 2; 861 860 case 1: 862 ®x = z;® $\C{// without fall through, z is uninitialized}$861 ®x = z;® §\C{// without fall through, z is uninitialized}§ 863 862 } 864 863 \end{cfa} … … 895 894 case 1: case 2: case 3: 896 895 ... 897 $\R{\LstCommentStyle{// implicit end of switch (break)}}$896 §\R{\LstCommentStyle{// implicit end of switch (break)}}§ 898 897 case 5: 899 898 ... 900 ®fallthru®; $\C{// explicit fall through}$899 ®fallthru®; §\C{// explicit fall through}§ 901 900 case 7: 902 901 ... 903 ®break® $\C{// explicit end of switch (redundant)}$902 ®break® §\C{// explicit end of switch (redundant)}§ 904 903 default: 905 904 j = 3; … … 922 921 \begin{cfa} 923 922 switch ( x ) { 924 ®int i = 0;® $\C{// allowed only at start}$923 ®int i = 0;® §\C{// allowed only at start}§ 925 924 case 0: 926 925 ... 927 ®int j = 0;® $\C{// disallowed}$926 ®int j = 0;® §\C{// disallowed}§ 928 927 case 1: 929 928 { 930 ®int k = 0;® $\C{// allowed at different nesting levels}$929 ®int k = 0;® §\C{// allowed at different nesting levels}§ 931 930 ... 932 ®case 2:® $\C{// disallow case in nested statements}$931 ®case 2:® §\C{// disallow case in nested statements}§ 933 932 } 934 933 ... … … 1004 1003 while () { sout | "empty"; break; } 1005 1004 do { sout | "empty"; break; } while (); 1006 for () { sout | "empty"; break; } $\C[3in]{sout | nl | nlOff;}$1007 1008 for ( 0 ) { sout | "A"; } sout | "zero"; $\C{sout | nl;}$1009 for ( 1 ) { sout | "A"; } $\C{sout | nl;}$1010 for ( 10 ) { sout | "A"; } $\C{sout | nl;}$1011 for ( ~= 10 ) { sout | "A"; } $\C{sout | nl;}$1012 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } $\C{sout | nl;}$1013 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } $\C{sout | nl;}$1014 for ( 0.5 ~ 5.5 ) { sout | "D"; } $\C{sout | nl;}$1015 for ( 0.5 -~ 5.5 ) { sout | "E"; } $\C{sout | nl;}$1016 for ( i; 10 ) { sout | i; } $\C{sout | nl;}$1017 for ( i; ~= 10 ) { sout | i; } $\C{sout | nl;}$1018 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } $\C{sout | nl;}$1019 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } $\C{sout | nl;}$1020 for ( i; 0.5 ~ 5.5 ) { sout | i; } $\C{sout | nl;}$1021 for ( i; 0.5 -~ 5.5 ) { sout | i; } $\C{sout | nl;}$1022 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } $\C{sout | nl;}$1023 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } $\C{sout | nl | nl | nl;}$1005 for () { sout | "empty"; break; } §\C[3in]{sout | nl | nlOff;}§ 1006 1007 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§ 1008 for ( 1 ) { sout | "A"; } §\C{sout | nl;}§ 1009 for ( 10 ) { sout | "A"; } §\C{sout | nl;}§ 1010 for ( ~= 10 ) { sout | "A"; } §\C{sout | nl;}§ 1011 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } §\C{sout | nl;}§ 1012 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } §\C{sout | nl;}§ 1013 for ( 0.5 ~ 5.5 ) { sout | "D"; } §\C{sout | nl;}§ 1014 for ( 0.5 -~ 5.5 ) { sout | "E"; } §\C{sout | nl;}§ 1015 for ( i; 10 ) { sout | i; } §\C{sout | nl;}§ 1016 for ( i; ~= 10 ) { sout | i; } §\C{sout | nl;}§ 1017 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§ 1018 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§ 1019 for ( i; 0.5 ~ 5.5 ) { sout | i; } §\C{sout | nl;}§ 1020 for ( i; 0.5 -~ 5.5 ) { sout | i; } §\C{sout | nl;}§ 1021 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl;}§ 1022 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl | nl | nl;}§ 1024 1023 1025 1024 enum { N = 10 }; 1026 for ( N ) { sout | "N"; } $\C{sout | nl;}$1027 for ( i; N ) { sout | i; } $\C{sout | nl;}$1028 for ( i; -~ N ) { sout | i; } $\C{sout | nl | nl | nl;}$1025 for ( N ) { sout | "N"; } §\C{sout | nl;}§ 1026 for ( i; N ) { sout | i; } §\C{sout | nl;}§ 1027 for ( i; -~ N ) { sout | i; } §\C{sout | nl | nl | nl;}§ 1029 1028 1030 1029 const int low = 3, high = 10, inc = 2; 1031 for ( i; low ~ high ~ inc + 1 ) { sout | i; } $\C{sout | nl;}$1032 for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } $\C{sout | nl;}$1033 for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } $\C{sout | nl;}$1034 for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } $\C{sout | nl;}$1035 for ( i; 2.1 ~ @ ~ @ ) { if ( i > 10.5 ) break; sout | i; i += 1.7; } $\C{sout | nl;}$1036 for ( i; @ -~ 10 ~ 2 ) { if ( i < 0 ) break; sout | i; } $\C{sout | nl;}$1037 for ( i; 12.1 ~ @ ~ @ ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; } $\C{sout | nl;}$1038 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } $\C{sout | nl;}$1039 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } $\C{sout | nl;}$1040 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } $\C{sout | nl;}$1041 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } $\C{sout | nl;}$1042 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } $\C{sout | nl;}$1043 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } $\C{sout | nl;}$1044 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } $\C{sout | nl;}$1045 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } $\C{sout | nl;}$1046 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } $\C{sout | nl;}$1047 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } $\C{sout | nl;}$1048 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } $\C{sout | nl;}\CRT$1030 for ( i; low ~ high ~ inc + 1 ) { sout | i; } §\C{sout | nl;}§ 1031 for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§ 1032 for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§ 1033 for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§ 1034 for ( i; 2.1 ~ @ ~ @ ) { if ( i > 10.5 ) break; sout | i; i += 1.7; } §\C{sout | nl;}§ 1035 for ( i; @ -~ 10 ~ 2 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§ 1036 for ( i; 12.1 ~ @ ~ @ ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; } §\C{sout | nl;}§ 1037 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§ 1038 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§ 1039 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1040 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1041 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§ 1042 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§ 1043 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1044 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1045 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1046 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1047 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}\CRT§ 1049 1048 \end{cfa} 1050 1049 & … … 1117 1116 The \Indexc{for}, \Indexc{while}, and \Indexc{do} loop-control allow an empty conditional, which implies a comparison value of ©1© (true). 1118 1117 \begin{cfa} 1119 while ( ®/* empty */® ) $\C{// while ( true )}$1120 for ( ®/* empty */® ) $\C{// for ( ; true; )}$1121 do ... while ( ®/* empty */® ) $\C{// do ... while ( true )}$1118 while ( ®/* empty */® ) §\C{// while ( true )}§ 1119 for ( ®/* empty */® ) §\C{// for ( ; true; )}§ 1120 do ... while ( ®/* empty */® ) §\C{// do ... while ( true )}§ 1122 1121 \end{cfa} 1123 1122 … … 1149 1148 If no type is specified for the loop index, it is the type of the high value H (when the low value is implicit) or the low value L. 1150 1149 \begin{cfa} 1151 for ( ®5® ) $\C{// typeof(5) anonymous-index; 5 is high value}$1152 for ( i; ®1.5® ~ 5.5 ) $\C{// typeof(1.5) i; 1.5 is low value}$1153 for ( ®int i®; 0 ~ 10 ~ 2 ) $\C{// int i; type is explicit}$1150 for ( ®5® ) §\C{// typeof(5) anonymous-index; 5 is high value}§ 1151 for ( i; ®1.5® ~ 5.5 ) §\C{// typeof(1.5) i; 1.5 is low value}§ 1152 for ( ®int i®; 0 ~ 10 ~ 2 ) §\C{// int i; type is explicit}§ 1154 1153 \end{cfa} 1155 1154 … … 1159 1158 H is implicit up-to exclusive range [0,H\R{)}. 1160 1159 \begin{cfa} 1161 for ( ®5® ) $\C{// for ( typeof(5) i; i < 5; i += 1 )}$1160 for ( ®5® ) §\C{// for ( typeof(5) i; i < 5; i += 1 )}§ 1162 1161 \end{cfa} 1163 1162 \item 1164 1163 ©~=© H is implicit up-to inclusive range [0,H\R{]}. 1165 1164 \begin{cfa} 1166 for ( ®~=® 5 ) $\C{// for ( typeof(5) i; i <= 5; i += 1 )}$1165 for ( ®~=® 5 ) §\C{// for ( typeof(5) i; i <= 5; i += 1 )}§ 1167 1166 \end{cfa} 1168 1167 \item 1169 1168 L ©~©\index{~@©~©} H is explicit up-to exclusive range [L,H\R{)}. 1170 1169 \begin{cfa} 1171 for ( 1 ®~® 5 ) $\C{// for ( typeof(1) i = 1; i < 5; i += 1 )}$1170 for ( 1 ®~® 5 ) §\C{// for ( typeof(1) i = 1; i < 5; i += 1 )}§ 1172 1171 \end{cfa} 1173 1172 \item 1174 1173 L ©~=©\index{~=@©~=©} H is explicit up-to inclusive range [L,H\R{]}. 1175 1174 \begin{cfa} 1176 for ( 1 ®~=® 5 ) $\C{// for ( typeof(1) i = 1; i <= 5; i += 1 )}$1175 for ( 1 ®~=® 5 ) §\C{// for ( typeof(1) i = 1; i <= 5; i += 1 )}§ 1177 1176 \end{cfa} 1178 1177 \item 1179 1178 L ©-~©\index{-~@©-~©} H is explicit down-to exclusive range [H,L\R{)}, where L and H are implicitly interchanged to make the range down-to. 1180 1179 \begin{cfa} 1181 for ( 1 ®-~® 5 ) $\C{// for ( typeof(1) i = 5; i > 0; i -= 1 )}$1180 for ( 1 ®-~® 5 ) §\C{// for ( typeof(1) i = 5; i > 0; i -= 1 )}§ 1182 1181 \end{cfa} 1183 1182 \item 1184 1183 L ©-~=©\index{-~=@©-~=©} H is explicit down-to inclusive range [H,L\R{]}, where L and H are implicitly interchanged to make the range down-to. 1185 1184 \begin{cfa} 1186 for ( 1 ®-~=® 5 ) $\C{// for ( typeof(1) i = 5; i >= 0; i -= 1 )}$1185 for ( 1 ®-~=® 5 ) §\C{// for ( typeof(1) i = 5; i >= 0; i -= 1 )}§ 1187 1186 \end{cfa} 1188 1187 \item 1189 1188 ©@© means put nothing in this field. 1190 1189 \begin{cfa} 1191 for ( i; 1 ~ ®@® ~ 2 ) $\C{// for ( typeof(1) i = 1; \R{/* empty */}; i += 2 )}$1192 for ( i; 1 ~ 10 ~ ®@® ) $\C{// for ( typeof(1) i = 1; i < 10; \R{/* empty */} )}$1193 for ( i; 1 ~ ®@® ~ ®@® ) $\C{// for ( typeof(1) i = 1; /*empty*/; \R{/* empty */} )}$1190 for ( i; 1 ~ ®@® ~ 2 ) §\C{// for ( typeof(1) i = 1; \R{/* empty */}; i += 2 )}§ 1191 for ( i; 1 ~ 10 ~ ®@® ) §\C{// for ( typeof(1) i = 1; i < 10; \R{/* empty */} )}§ 1192 for ( i; 1 ~ ®@® ~ ®@® ) §\C{// for ( typeof(1) i = 1; /*empty*/; \R{/* empty */} )}§ 1194 1193 \end{cfa} 1195 1194 L cannot be elided for the up-to range, \lstinline{@ ~ 5}, and H for the down-to range, \lstinline{1 -~ @}, because then the loop index is uninitialized. … … 1198 1197 ©:© means low another index. 1199 1198 \begin{cfa} 1200 for ( i; 5 ®:® j; 2 ~ 12 ~ 3 ) $\C{// for ( typeof(i) i = 1, j = 2; i < 5 \&\& j < 12; i += 1, j += 3 )}$1199 for ( i; 5 ®:® j; 2 ~ 12 ~ 3 ) §\C{// for ( typeof(i) i = 1, j = 2; i < 5 \&\& j < 12; i += 1, j += 3 )}§ 1201 1200 \end{cfa} 1202 1201 \end{itemize} 1203 1202 \R{Warning}: specifying the down-to range maybe unexpected because the loop control \emph{implicitly} switches the L and H values (and toggles the increment/decrement for I): 1204 1203 \begin{cfa} 1205 for ( i; 1 ~ 10 ) ${\C{// up range}$1206 for ( i; 1 -~ 10 ) ${\C{// down range}$1207 for ( i; ®10 -~ 1® ) ${\C{// \R{WRONG down range!}}}$1204 for ( i; 1 ~ 10 ) §{\C{// up range}§ 1205 for ( i; 1 -~ 10 ) §{\C{// down range}§ 1206 for ( i; ®10 -~ 1® ) §{\C{// \R{WRONG down range!}}}§ 1208 1207 \end{cfa} 1209 1208 The reason for this semantics is that the range direction can be toggled by adding/removing the minus, ©'-'©, versus interchanging the L and H expressions, which has a greater chance of introducing errors. … … 1361 1360 Grouping heterogeneous data into an \newterm{aggregate} (structure/union) is a common programming practice, and aggregates may be nested: 1362 1361 \begin{cfa} 1363 struct Person { $\C{// aggregate}$1364 struct Name { $\C{// nesting}$1362 struct Person { §\C{// aggregate}§ 1363 struct Name { §\C{// nesting}§ 1365 1364 char first[20], last[20]; 1366 1365 } name; 1367 struct Address { $\C{// nesting}$1366 struct Address { §\C{// nesting}§ 1368 1367 ... 1369 1368 } address; … … 1374 1373 \begin{cfa} 1375 1374 Person p 1376 ®p.®name; ®p.®address; ®p.®sex; $\C{// access containing fields}$1375 ®p.®name; ®p.®address; ®p.®sex; §\C{// access containing fields}§ 1377 1376 \end{cfa} 1378 1377 which extends to multiple levels of qualification for nested aggregates and multiple aggregates. 1379 1378 \begin{cfa} 1380 1379 struct Ticket { ... } t; 1381 ®p.name®.first; ®p.address®.street; $\C{// access nested fields}$1382 ®t.®departure; ®t.®cost; $\C{// access multiple aggregate}$1380 ®p.name®.first; ®p.address®.street; §\C{// access nested fields}§ 1381 ®t.®departure; ®t.®cost; §\C{// access multiple aggregate}§ 1383 1382 \end{cfa} 1384 1383 Repeated aggregate qualification is tedious and makes code difficult to read. … … 1389 1388 \begin{cfa} 1390 1389 struct S { 1391 struct $\R{\LstCommentStyle{/* unnamed */}}${ int g, h; } __attribute__(( aligned(64) ));1390 struct §\R{\LstCommentStyle{/* unnamed */}}§ { int g, h; } __attribute__(( aligned(64) )); 1392 1391 int tag; 1393 union $\R{\LstCommentStyle{/* unnamed */}}${1392 union §\R{\LstCommentStyle{/* unnamed */}}§ { 1394 1393 struct { char c1, c2; } __attribute__(( aligned(128) )); 1395 1394 struct { int i1, i2; }; … … 1405 1404 struct S { 1406 1405 char ®c®; int ®i®; double ®d®; 1407 void f( /* S * this */ ) { $\C{// implicit ``this'' parameter}$1408 ®c®; ®i®; ®d®; $\C{// this->c; this->i; this->d;}$1406 void f( /* S * this */ ) { §\C{// implicit ``this'' parameter}§ 1407 ®c®; ®i®; ®d®; §\C{// this->c; this->i; this->d;}§ 1409 1408 } 1410 1409 } … … 1414 1413 \begin{cfa} 1415 1414 struct T { 1416 char ®m®; int ®i®; double ®n®; $\C{// derived class variables}$1415 char ®m®; int ®i®; double ®n®; §\C{// derived class variables}§ 1417 1416 }; 1418 1417 struct S : public T { 1419 char ®c®; int ®i®; double ®d®; $\C{// class variables}$1418 char ®c®; int ®i®; double ®d®; §\C{// class variables}§ 1420 1419 void g( double ®d®, T & t ) { 1421 d; ®t®.m; ®t®.i; ®t®.n; $\C{// function parameter}$1422 c; i; ®this->®d; ®S::®d; $\C{// class S variables}$1423 m; ®T::®i; n; $\C{// class T variables}$1420 d; ®t®.m; ®t®.i; ®t®.n; §\C{// function parameter}§ 1421 c; i; ®this->®d; ®S::®d; §\C{// class S variables}§ 1422 m; ®T::®i; n; §\C{// class T variables}§ 1424 1423 } 1425 1424 }; … … 1431 1430 Hence, the qualified fields become variables with the side-effect that it is simpler to write, easier to read, and optimize field references in a block. 1432 1431 \begin{cfa} 1433 void f( S & this ) ®with ( this )® { $\C{// with statement}$1434 ®c®; ®i®; ®d®; $\C{// this.c, this.i, this.d}$1432 void f( S & this ) ®with ( this )® { §\C{// with statement}§ 1433 ®c®; ®i®; ®d®; §\C{// this.c, this.i, this.d}§ 1435 1434 } 1436 1435 \end{cfa} 1437 1436 with the generality of opening multiple aggregate-parameters: 1438 1437 \begin{cfa} 1439 void g( S & s, T & t ) ®with ( s, t )® { $\C{// multiple aggregate parameters}$1440 c; ®s.®i; d; $\C{// s.c, s.i, s.d}$1441 m; ®t.®i; n; $\C{// t.m, t.i, t.n}$1438 void g( S & s, T & t ) ®with ( s, t )® {§\C{// multiple aggregate parameters}§ 1439 c; ®s.®i; d; §\C{// s.c, s.i, s.d}§ 1440 m; ®t.®i; n; §\C{// t.m, t.i, t.n}§ 1442 1441 } 1443 1442 \end{cfa} … … 1462 1461 struct R { int ®i®; int j; double ®m®; } r, w; 1463 1462 with ( r, q ) { 1464 j + k; $\C{// unambiguous, r.j + q.k}$1465 m = 5.0; $\C{// unambiguous, q.m = 5.0}$1466 m = 1; $\C{// unambiguous, r.m = 1}$1467 int a = m; $\C{// unambiguous, a = r.i }$1468 double b = m; $\C{// unambiguous, b = q.m}$1469 int c = r.i + q.i; $\C{// disambiguate with qualification}$1470 (double)m; $\C{// disambiguate with cast}$1463 j + k; §\C{// unambiguous, r.j + q.k}§ 1464 m = 5.0; §\C{// unambiguous, q.m = 5.0}§ 1465 m = 1; §\C{// unambiguous, r.m = 1}§ 1466 int a = m; §\C{// unambiguous, a = r.i }§ 1467 double b = m; §\C{// unambiguous, b = q.m}§ 1468 int c = r.i + q.i; §\C{// disambiguate with qualification}§ 1469 (double)m; §\C{// disambiguate with cast}§ 1471 1470 } 1472 1471 \end{cfa} … … 1476 1475 \begin{cfa} 1477 1476 with ( r ) { 1478 i; $\C{// unambiguous, r.i}$1477 i; §\C{// unambiguous, r.i}§ 1479 1478 with ( q ) { 1480 i; $\C{// unambiguous, q.i}$1479 i; §\C{// unambiguous, q.i}§ 1481 1480 } 1482 1481 } … … 1485 1484 A cast can also be used to disambiguate among overload variables in a ©with© \emph{expression}: 1486 1485 \begin{cfa} 1487 with ( w ) { ... } $\C{// ambiguous, same name and no context}$1488 with ( (Q)w ) { ... } $\C{// unambiguous, cast}$1486 with ( w ) { ... } §\C{// ambiguous, same name and no context}§ 1487 with ( (Q)w ) { ... } §\C{// unambiguous, cast}§ 1489 1488 \end{cfa} 1490 1489 Because there is no left-side in the ©with© expression to implicitly disambiguate between the ©w© variables, it is necessary to explicitly disambiguate by casting ©w© to type ©Q© or ©R©. … … 1493 1492 \begin{cfa} 1494 1493 void f( S & s, char c ) with ( s ) { 1495 ®s.c = c;® i = 3; d = 5.5; $\C{// initialize fields}$1494 ®s.c = c;® i = 3; d = 5.5; §\C{// initialize fields}§ 1496 1495 } 1497 1496 \end{cfa} … … 1499 1498 To solve this problem, parameters \emph{not} explicitly opened are treated like an initialized aggregate: 1500 1499 \begin{cfa} 1501 struct Params { $\C{// s explicitly opened so S \& s elided}$1500 struct Params { §\C{// s explicitly opened so S \& s elided}§ 1502 1501 char c; 1503 1502 } params; … … 1505 1504 and implicitly opened \emph{after} a function-body open, to give them higher priority: 1506 1505 \begin{cfa} 1507 void f( S & s, char ®c® ) with ( s ) ®with( $\emph{\R{params}}$)® { // syntax not allowed, illustration only1506 void f( S & s, char ®c® ) with ( s ) ®with( §\emph{\R{params}}§ )® { // syntax not allowed, illustration only 1508 1507 s.c = ®c;® i = 3; d = 5.5; 1509 1508 } … … 1538 1537 1539 1538 \begin{cfa} 1540 exception_t E {}; $\C{// exception type}$1539 exception_t E {}; §\C{// exception type}§ 1541 1540 void f(...) { 1542 ... throw E{}; ... $\C{// termination}$1543 ... throwResume E{}; ... $\C{// resumption}$1541 ... throw E{}; ... §\C{// termination}§ 1542 ... throwResume E{}; ... §\C{// resumption}§ 1544 1543 } 1545 1544 try { 1546 1545 f(...); 1547 } catch( E e ; $boolean-predicate$ ) { $\C{// termination handler}$1546 } catch( E e ; §boolean-predicate§ ) { §\C{// termination handler}§ 1548 1547 // recover and continue 1549 } catchResume( E e ; $boolean-predicate$ ) { $\C{// resumption handler}$1548 } catchResume( E e ; §boolean-predicate§ ) { §\C{// resumption handler}§ 1550 1549 // repair and return 1551 1550 } finally { … … 1624 1623 For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way: 1625 1624 \begin{cfa} 1626 int ®(*®f®())[®5®]® {...}; $\C{// definition}$1627 ... ®(*®f®())[®3®]® += 1; $\C{// usage}$1625 int ®(*®f®())[®5®]® {...}; §\C{// definition}§ 1626 ... ®(*®f®())[®3®]® += 1; §\C{// usage}§ 1628 1627 \end{cfa} 1629 1628 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}). … … 1870 1869 For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage 1871 1870 \begin{cfa} 1872 p2 = p1 + x; $\C{// compiler infers *p2 = *p1 + x;}$1871 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§ 1873 1872 \end{cfa} 1874 1873 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. … … 1878 1877 In C, objects of pointer type always manipulate the pointer object's address: 1879 1878 \begin{cfa} 1880 p1 = p2; $\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}$1881 p2 = p1 + x; $\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}$1879 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§ 1880 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§ 1882 1881 \end{cfa} 1883 1882 even though the assignment to ©p2© is likely incorrect, and the programmer probably meant: 1884 1883 \begin{cfa} 1885 p1 = p2; $\C{// pointer address assignment}$1886 ®*®p2 = ®*®p1 + x; $\C{// pointed-to value assignment / operation}$1884 p1 = p2; §\C{// pointer address assignment}§ 1885 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§ 1887 1886 \end{cfa} 1888 1887 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©). … … 1901 1900 \begin{cfa} 1902 1901 int x, y, ®&® r1, ®&® r2, ®&&® r3; 1903 ®&®r1 = &x; $\C{// r1 points to x}$1904 ®&®r2 = &r1; $\C{// r2 points to x}$1905 ®&®r1 = &y; $\C{// r1 points to y}$1906 ®&&®r3 = ®&®&r2; $\C{// r3 points to r2}$1907 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); $\C{// implicit dereferencing}$1902 ®&®r1 = &x; §\C{// r1 points to x}§ 1903 ®&®r2 = &r1; §\C{// r2 points to x}§ 1904 ®&®r1 = &y; §\C{// r1 points to y}§ 1905 ®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§ 1906 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§ 1908 1907 \end{cfa} 1909 1908 Except for auto-dereferencing by the compiler, this reference example is the same as the previous pointer example. … … 1920 1919 For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}): 1921 1920 \begin{cfa} 1922 (&®*®)r1 = &x; $\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}$1921 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§ 1923 1922 \end{cfa} 1924 1923 Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}): 1925 1924 \begin{cfa} 1926 (&(&®*®)®*®)r3 = &(&®*®)r2; $\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}$1925 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§ 1927 1926 \end{cfa} 1928 1927 Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth. … … 1932 1931 int x, *p1 = &x, **p2 = &p1, ***p3 = &p2, 1933 1932 &r1 = x, &&r2 = r1, &&&r3 = r2; 1934 ***p3 = 3; $\C{// change x}$1935 r3 = 3; $\C{// change x, ***r3}$1936 **p3 = ...; $\C{// change p1}$1937 &r3 = ...; $\C{// change r1, (\&*)**r3, 1 cancellation}$1938 *p3 = ...; $\C{// change p2}$1939 &&r3 = ...; $\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}$1940 &&&r3 = p3; $\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}$1933 ***p3 = 3; §\C{// change x}§ 1934 r3 = 3; §\C{// change x, ***r3}§ 1935 **p3 = ...; §\C{// change p1}§ 1936 &r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§ 1937 *p3 = ...; §\C{// change p2}§ 1938 &&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§ 1939 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§ 1941 1940 \end{cfa} 1942 1941 Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types. … … 1945 1944 As for a pointer type, a reference type may have qualifiers: 1946 1945 \begin{cfa} 1947 const int cx = 5; $\C{// cannot change cx;}$1948 const int & cr = cx; $\C{// cannot change what cr points to}$1949 ®&®cr = &cx; $\C{// can change cr}$1950 cr = 7; $\C{// error, cannot change cx}$1951 int & const rc = x; $\C{// must be initialized}$1952 ®&®rc = &x; $\C{// error, cannot change rc}$1953 const int & const crc = cx; $\C{// must be initialized}$1954 crc = 7; $\C{// error, cannot change cx}$1955 ®&®crc = &cx; $\C{// error, cannot change crc}$1946 const int cx = 5; §\C{// cannot change cx;}§ 1947 const int & cr = cx; §\C{// cannot change what cr points to}§ 1948 ®&®cr = &cx; §\C{// can change cr}§ 1949 cr = 7; §\C{// error, cannot change cx}§ 1950 int & const rc = x; §\C{// must be initialized}§ 1951 ®&®rc = &x; §\C{// error, cannot change rc}§ 1952 const int & const crc = cx; §\C{// must be initialized}§ 1953 crc = 7; §\C{// error, cannot change cx}§ 1954 ®&®crc = &cx; §\C{// error, cannot change crc}§ 1956 1955 \end{cfa} 1957 1956 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}: 1958 1957 \begin{cfa} 1959 int & const cr = *0; $\C{// where 0 is the int * zero}$1958 int & const cr = *0; §\C{// where 0 is the int * zero}§ 1960 1959 \end{cfa} 1961 1960 Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management: … … 1964 1963 cr = 5; 1965 1964 free( &cr ); 1966 cr = 7; $\C{// unsound pointer dereference}$1965 cr = 7; §\C{// unsound pointer dereference}§ 1967 1966 \end{cfa} 1968 1967 … … 1972 1971 \begin{cquote} 1973 1972 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 1974 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C y}} & \multicolumn{1}{c}{\textbf{\CFA}} \\1973 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}} \\ 1975 1974 \begin{cfa} 1976 1975 const int * ®const® * ®const® ccp; … … 1988 1987 Finally, like pointers, references are usable and composable with other type operators and generators. 1989 1988 \begin{cfa} 1990 int w, x, y, z, & ar[3] = { x, y, z }; $\C{// initialize array of references}$1991 &ar[1] = &w; $\C{// change reference array element}$1992 typeof( ar[1] ) p; $\C{// (gcc) is int, \ie the type of referenced object}$1993 typeof( &ar[1] ) q; $\C{// (gcc) is int \&, \ie the type of reference}$1994 sizeof( ar[1] ) == sizeof( int ); $\C{// is true, \ie the size of referenced object}$1995 sizeof( &ar[1] ) == sizeof( int *) $\C{// is true, \ie the size of a reference}$1989 int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§ 1990 &ar[1] = &w; §\C{// change reference array element}§ 1991 typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§ 1992 typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§ 1993 sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§ 1994 sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§ 1996 1995 \end{cfa} 1997 1996 … … 2010 2009 Therefore, for pointer/reference initialization, the initializing value must be an address not a value. 2011 2010 \begin{cfa} 2012 int * p = &x; $\C{// assign address of x}$2013 ®int * p = x;® $\C{// assign value of x}$2014 int & r = x; $\C{// must have address of x}$2011 int * p = &x; §\C{// assign address of x}§ 2012 ®int * p = x;® §\C{// assign value of x}§ 2013 int & r = x; §\C{// must have address of x}§ 2015 2014 \end{cfa} 2016 2015 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). … … 2021 2020 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. 2022 2021 \begin{cfa} 2023 int & f( int & r ); $\C{// reference parameter and return}$2024 z = f( x ) + f( y ); $\C{// reference operator added, temporaries needed for call results}$2022 int & f( int & r ); §\C{// reference parameter and return}§ 2023 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§ 2025 2024 \end{cfa} 2026 2025 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©. … … 2049 2048 void f( int & r ); 2050 2049 void g( int * p ); 2051 f( 3 ); g( ®&®3 ); $\C{// compiler implicit generates temporaries}$2052 f( x + y ); g( ®&®(x + y) ); $\C{// compiler implicit generates temporaries}$2050 f( 3 ); g( ®&®3 ); §\C{// compiler implicit generates temporaries}§ 2051 f( x + y ); g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§ 2053 2052 \end{cfa} 2054 2053 Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{ … … 2061 2060 \begin{cfa} 2062 2061 void f( int i ); 2063 void (* fp)( int ); $\C{// routine pointer}$2064 fp = f; $\C{// reference initialization}$2065 fp = &f; $\C{// pointer initialization}$2066 fp = *f; $\C{// reference initialization}$2067 fp(3); $\C{// reference invocation}$2068 (*fp)(3); $\C{// pointer invocation}$2062 void (* fp)( int ); §\C{// routine pointer}§ 2063 fp = f; §\C{// reference initialization}§ 2064 fp = &f; §\C{// pointer initialization}§ 2065 fp = *f; §\C{// reference initialization}§ 2066 fp(3); §\C{// reference invocation}§ 2067 (*fp)(3); §\C{// pointer invocation}§ 2069 2068 \end{cfa} 2070 2069 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. 2071 2070 Instead, a routine object should be referenced by a ©const© reference: 2072 2071 \begin{cfa} 2073 ®const® void (®&® fr)( int ) = f; $\C{// routine reference}$2074 fr = ... $\C{// error, cannot change code}$2075 &fr = ...; $\C{// changing routine reference}$2076 fr( 3 ); $\C{// reference call to f}$2077 (*fr)(3); $\C{// error, incorrect type}$2072 ®const® void (®&® fr)( int ) = f; §\C{// routine reference}§ 2073 fr = ...; §\C{// error, cannot change code}§ 2074 &fr = ...; §\C{// changing routine reference}§ 2075 fr( 3 ); §\C{// reference call to f}§ 2076 (*fr)(3); §\C{// error, incorrect type}§ 2078 2077 \end{cfa} 2079 2078 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{ … … 2097 2096 int x, * px, ** ppx, *** pppx, **** ppppx; 2098 2097 int & rx = x, && rrx = rx, &&& rrrx = rrx ; 2099 x = rrrx; $\C[2.0in]{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}$2100 px = &rrrx; $\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (\&x)}$2101 ppx = &&rrrx; $\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (\&rx)}$2102 pppx = &&&rrrx; $\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (\&rrx)}$2103 ppppx = &&&&rrrx; $\C{// starting from \&\&\&rrrx, \&\&\&\&rrrx is an rvalue with type int **** (\&rrrx)}$2098 x = rrrx; §\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§ 2099 px = &rrrx; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (\&x)}§ 2100 ppx = &&rrrx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (\&rx)}§ 2101 pppx = &&&rrrx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (\&rrx)}§ 2102 ppppx = &&&&rrrx; §\C{// starting from \&\&\&rrrx, \&\&\&\&rrrx is an rvalue with type int **** (\&rrrx)}§ 2104 2103 \end{cfa} 2105 2104 The following example shows the second rule applied to different \Index{lvalue} contexts: … … 2107 2106 int x, * px, ** ppx, *** pppx; 2108 2107 int & rx = x, && rrx = rx, &&& rrrx = rrx ; 2109 rrrx = 2; $\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}$2110 &rrrx = px; $\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (rx)}$2111 &&rrrx = ppx; $\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (rrx)}$2112 &&&rrrx = pppx; $\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (rrrx)}\CRT$2108 rrrx = 2; §\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§ 2109 &rrrx = px; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (rx)}§ 2110 &&rrrx = ppx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (rrx)}§ 2111 &&&rrrx = pppx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (rrrx)}§ 2113 2112 \end{cfa} 2114 2113 … … 2123 2122 \begin{cfa} 2124 2123 int x; 2125 x + 1; $\C[2.0in]{// lvalue variable (int) converts to rvalue for expression}$2124 x + 1; §\C{// lvalue variable (int) converts to rvalue for expression}§ 2126 2125 \end{cfa} 2127 2126 An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped. … … 2133 2132 \begin{cfa} 2134 2133 int x, &r = x, f( int p ); 2135 x = ®r® + f( ®r® ); $\C{// lvalue reference converts to rvalue}$2134 x = ®r® + f( ®r® ); §\C{// lvalue reference converts to rvalue}§ 2136 2135 \end{cfa} 2137 2136 An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped. … … 2140 2139 lvalue to reference conversion: \lstinline[deletekeywords=lvalue]{lvalue-type cv1 T} converts to ©cv2 T &©, which allows implicitly converting variables to references. 2141 2140 \begin{cfa} 2142 int x, &r = ®x®, f( int & p ); $\C{// lvalue variable (int) convert to reference (int \&)}$2143 f( ®x® ); $\C{// lvalue variable (int) convert to reference (int \&)}\CRT$2141 int x, &r = ®x®, f( int & p ); §\C{// lvalue variable (int) convert to reference (int \&)}§ 2142 f( ®x® ); §\C{// lvalue variable (int) convert to reference (int \&)}§ 2144 2143 \end{cfa} 2145 2144 Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost. … … 2151 2150 \begin{cfa} 2152 2151 int x, & f( int & p ); 2153 f( ®x + 3® ); $\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}$2154 ®&f®(...) = &x; $\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT$2152 f( ®x + 3® ); §\C{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}§ 2153 ®&f®(...) = &x; §\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}§ 2155 2154 \end{cfa} 2156 2155 In both case, modifications to the temporary are inaccessible (\Index{warning}). … … 2319 2318 2320 2319 2320 \section{\lstinline{string} Type} 2321 \label{s:stringType} 2322 2323 The \CFA \Indexc{string} type is for manipulation of dynamically-size character-strings versus C \Indexc{char *} type for manipulation of statically-size null-terminated character-strings. 2324 That is, the amount of storage for a \CFA string changes dynamically at runtime to fit the string size, whereas the amount of storage for a C string is fixed at compile time. 2325 Hence, a ©string© declaration does not specify a maximum length; 2326 as a string dynamically grows and shrinks in size, so does its underlying storage. 2327 In contrast, a C string also dynamically grows and shrinks is size, but its underlying storage is fixed. 2328 The maximum storage for a \CFA ©string© value is ©size_t© characters, which is $2^{32}$ or $2^{64}$ respectively. 2329 A \CFA string manages its length separately from the string, so there is no null (©'\0'©) terminating value at the end of a string value. 2330 Hence, a \CFA string cannot be passed to a C string manipulation routine, such as ©strcat©. 2331 Like C strings, the characters in a ©string© are numbered starting from 0. 2332 2333 The following operations have been defined to manipulate an instance of type ©string©. 2334 The discussion assumes the following declarations and assignment statements are executed. 2335 \begin{cfa} 2336 #include ®<string.hfa>® 2337 ®string® s, peter, digit, alpha, punctuation, ifstmt; 2338 int i; 2339 peter = "PETER"; 2340 digit = "0123456789"; 2341 punctuation = "().,"; 2342 ifstmt = "IF (A > B) {"; 2343 \end{cfa} 2344 Note, the include file \Indexc{string.hfa} to access type ©string©. 2345 2346 2347 \subsection{Implicit String Conversions} 2348 2349 The types ©char©, ©char *©, ©int©, ©double©, ©_Complex©, including signness and different sizes, implicitly convert to type ©string©. 2350 \VRef[Figure]{f:ImplicitStringConversions} shows examples of implicit conversion between C strings, integral, floating-point and complex types to ©string© 2351 The implicit conversions can be specified explicitly, as in: 2352 \begin{cfa} 2353 s = string( "abc" ); // converts char * to string 2354 s = string( 5 ); // converts int to string 2355 s = string( 5.5 ); // converts double to string 2356 \end{cfa} 2357 Conversions from ©string© to ©char *© are supported but with restrictions. 2358 Explicit As well, when a string is converted to a ©char *©, the storage for the ©char *© is created by the conversion operation, which must be subsequently deleted: 2359 \begin{cfa} 2360 string x = "abc"; 2361 char *p = x; // convert from string to char * 2362 ... 2363 delete p; // free storage created for p 2364 \end{cfa} 2365 2366 \begin{figure} 2367 \begin{tabular}{@{}l@{\hspace{15pt}}|@{\hspace{15pt}}l@{}} 2368 \begin{cfa} 2369 // string s = 5; sout | s; 2370 string s; 2371 // conversion of char and char * to string 2372 s = 'x'; §\CD{sout | s;}§ 2373 s = "abc"; §\CD{sout | s;}§ 2374 char cs[5] = "abc"; 2375 s = cs; §\CD{sout | s;}§ 2376 // conversion of integral, floating-point, and complex to string 2377 s = 45hh; §\CD{sout | s;}§ 2378 s = 45h; §\CD{sout | s;}§ 2379 s = -(ssize_t)MAX - 1; §\CD{sout | s;}§ 2380 s = (size_t)MAX; §\CD{sout | s;}§ 2381 s = 5.5; §\CD{sout | s;}§ 2382 s = 5.5L; §\CD{sout | s;}§ 2383 s = 5.5+3.4i; §\CD{sout | s;}§ 2384 s = 5.5L+3.4Li; §\CD{sout | s;}§ 2385 // safe conversion from string to char * 2386 strncpy( cs, s, sizeof(cs) ); §\CD{sout | cs;}§ 2387 char * cp = s; §\CD{sout | cp; // ownership}§ 2388 delete( cp ); 2389 cp = s + ' ' + s; §\CD{sout | cp; // ownership}§ 2390 delete( cp ); 2391 \end{cfa} 2392 & 2393 \begin{cfa} 2394 2395 2396 2397 x 2398 abc 2399 2400 abc 2401 2402 45 2403 45 2404 -9223372036854775808 2405 18446744073709551615 2406 5.5 2407 5.5 2408 5.5+3.4i 2409 5.5+3.4i 2410 2411 5.5+ 2412 5.5+3.4i 2413 2414 5.5+3.4i 5.5+3.4i 2415 2416 \end{cfa} 2417 \end{tabular} 2418 \caption{Implicit String Conversions} 2419 \label{f:ImplicitStringConversions} 2420 \end{figure} 2421 2422 2423 \subsection{Comparison Operators} 2424 2425 The binary relational and equality operators ©<©, ©<=©, ©>©, ©>=©, ©==©, ©!=© compare ©string© using lexicographical ordering, where longer strings are greater than shorter strings. 2426 2427 2428 \subsection{Concatenation} 2429 2430 The binary operator ©+© concatenates two strings. 2431 \begin{cfa} 2432 s = peter + digit; §\C{// s is assigned "PETER0123456789"}§ 2433 s += peter; §\C{// s is assigned "PETER0123456789PETER"}§ 2434 \end{cfa} 2435 There is also an assignment form ©+=©. 2436 2437 2438 \subsection{Repetition} 2439 2440 The binary operator \Indexc{*} returns a string that is the string repeated ©n© times. 2441 If ©n = 0©, a zero length string, ©""© is returned. 2442 \begin{cfa} 2443 s = (peter + ' ') * 3; §\C{// s is assigned "PETER PETER PETER"}§ 2444 \end{cfa} 2445 There is also an assignment form ©*=©. 2446 2447 2448 \subsection{Length} 2449 2450 The ©length© operation 2451 \begin{cfa} 2452 int length() 2453 \end{cfa} 2454 returns the length of a string variable. 2455 \begin{cfa} 2456 i = peter.length(); §\C{// i is assigned the value 5}§ 2457 \end{cfa} 2458 2459 2460 \subsection{Substring} 2461 The substring operation: 2462 \begin{cfa} 2463 string operator () (int start, int lnth); 2464 \end{cfa} 2465 performs a substring operation that returns the string starting at a specified position (©start©) in the current string, and having the specified length (©lnth©). 2466 A negative starting position is a specification from the right end of the string. 2467 A negative length means that characters are selected in the opposite (right to left) direction from the starting position. 2468 If the substring request extends beyond the beginning or end of the string, it is clipped (shortened) to the bounds of the string. 2469 If the substring request is completely outside of the original string, a null string located at the end of the original string is returned. 2470 \begin{cfa} 2471 s = peter( 2, 3 ); §\C{// s is assigned "ETE"}§ 2472 s = peter( 4, -3 ); §\C{// s is assigned "ETE", length is opposite direction}§ 2473 s = peter( 2, 8 ); §\C{// s is assigned "ETER", length is clipped to 4}§ 2474 s = peter( 0, -1 ); §\C{// s is assigned "", beyond string so clipped to null}§ 2475 s = peter(-1, -1 ); §\C{// s is assigned "R", start and length are negative}§ 2476 \end{cfa} 2477 The substring operation can also appear on the left hand side of the assignment operator. 2478 The substring is replaced by the value on the right hand side of the assignment. 2479 The length of the right-hand-side value may be shorter, the same length, or longer than the length of the substring that is selected on the left hand side of the assignment. 2480 \begin{cfa}[mathescape=false] 2481 digit( 3, 3 ) = ""; §\C{// digit is assigned "0156789"}§ 2482 digit( 4, 3 ) = "xyz"; §\C{// digit is assigned "015xyz9"}§ 2483 digit( 7, 0 ) = "***"; §\C{// digit is assigned "015xyz***9"}§ 2484 digit(-4, 3 ) = "$$$"; §\C{// digit is assigned "015xyz\$\$\$9"}§ 2485 \end{cfa} 2486 A substring is treated as a pointer into the base (substringed) string rather than creating a copy of the subtext. 2487 As with all pointers, if the item they are pointing at is changed, then the pointer is referring to the changed item. 2488 Pointers to the result value of a substring operation are defined to always start at the same location in their base string as long as that starting location exists, independent of changes to themselves or the base string. 2489 However, if the base string value changes, this may affect the values of one or more of the substrings to that base string. 2490 If the base string value shortens so that its end is before the starting location of a substring, resulting in the substring starting location disappearing, the substring becomes a null string located at the end of the base string. 2491 2492 The following example illustrates passing the results of substring operations by reference and by value to a subprogram. 2493 Notice the side-effects to other reference parameters as one is modified. 2494 \begin{cfa} 2495 main() { 2496 string x = "xxxxxxxxxxxxx"; 2497 test( x, x(1,3), x(3,3), x(5,5), x(9,5), x(9,5) ); 2498 } 2499 2500 // x, a, b, c, & d are substring results passed by reference 2501 // e is a substring result passed by value 2502 void test(string &x, string &a, string &b, string &c, string &d, string e) { 2503 §\C{// x a b c d e}§ 2504 a( 1, 2 ) = "aaa"; §\C{// aaaxxxxxxxxxxx aaax axx xxxxx xxxxx xxxxx}§ 2505 b( 2, 12 ) = "bbb"; §\C{// aaabbbxxxxxxxxx aaab abbb bbxxx xxxxx xxxxx}§ 2506 c( 4, 5 ) = "ccc"; §\C{// aaabbbxcccxxxxxx aaab abbb bbxccc ccxxx xxxxx}§ 2507 c = "yyy"; §\C{// aaabyyyxxxxxx aaab abyy yyy xxxxx xxxxx}§ 2508 d( 1, 3 ) = "ddd"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx xxxxx}§ 2509 e( 1, 3 ) = "eee"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx eeexx}§ 2510 x = e; §\C{// eeexx eeex exx x eeexx}§ 2511 } 2512 \end{cfa} 2513 2514 There is an assignment form of substring in which only the starting position is specified and the length is assumed to be the remainder of the string. 2515 \begin{cfa} 2516 string operator () (int start); 2517 \end{cfa} 2518 For example: 2519 \begin{cfa} 2520 s = peter( 2 ); §\C{// s is assigned "ETER"}§ 2521 peter( 2 ) = "IPER"; §\C{// peter is assigned "PIPER"}§ 2522 \end{cfa} 2523 It is also possible to substring using a string as the index for selecting the substring portion of the string. 2524 \begin{cfa} 2525 string operator () (const string &index); 2526 \end{cfa} 2527 For example: 2528 \begin{cfa}[mathescape=false] 2529 digit( "xyz$$$" ) = "678"; §\C{// digit is assigned "0156789"}§ 2530 digit( "234") = "***"; §\C{// digit is assigned "0156789***"}§ 2531 \end{cfa} 2532 %$ 2533 2534 2535 \subsection{Searching} 2536 2537 The ©index© operation 2538 \begin{cfa} 2539 int index( const string &key, int start = 1, occurrence occ = first ); 2540 \end{cfa} 2541 returns the position of the first or last occurrence of the ©key© (depending on the occurrence indicator ©occ© that is either ©first© or ©last©) in the current string starting the search at position ©start©. 2542 If the ©key© does not appear in the current string, the length of the current string plus one is returned. 2543 %If the ©key© has zero length, the value 1 is returned regardless of what the current string contains. 2544 A negative starting position is a specification from the right end of the string. 2545 \begin{cfa} 2546 i = digit.index( "567" ); §\C{// i is assigned 3}§ 2547 i = digit.index( "567", 7 ); §\C{// i is assigned 11}§ 2548 i = digit.index( "567", -1, last ); §\C{// i is assigned 3}§ 2549 i = peter.index( "E", 5, last ); §\C{// i is assigned 4}§ 2550 \end{cfa} 2551 2552 The next two string operations test a string to see if it is or is not composed completely of a particular class of characters. 2553 For example, are the characters of a string all alphabetic or all numeric? 2554 Use of these operations involves a two step operation. 2555 First, it is necessary to create an instance of type ©strmask© and initialize it to a string containing the characters of the particular character class, as in: 2556 \begin{cfa} 2557 strmask digitmask = digit; 2558 strmask alphamask = string( "abcdefghijklmnopqrstuvwxyz" ); 2559 \end{cfa} 2560 Second, the character mask is used in the functions ©include© and ©exclude© to check a string for compliance of its characters with the characters indicated by the mask. 2561 2562 The ©include© operation 2563 \begin{cfa} 2564 int include( const strmask &, int = 1, occurrence occ = first ); 2565 \end{cfa} 2566 returns the position of the first or last character (depending on the occurrence indicator, which is either ©first© or ©last©) in the current string that does not appear in the ©mask© starting the search at position ©start©; 2567 hence it skips over characters in the current string that are included (in) the ©mask©. 2568 The characters in the current string do not have to be in the same order as the ©mask©. 2569 If all the characters in the current string appear in the ©mask©, the length of the current string plus one is returned, regardless of which occurrence is being searched for. 2570 A negative starting position is a specification from the right end of the string. 2571 \begin{cfa} 2572 i = peter.include( digitmask ); §\C{// i is assigned 1}§ 2573 i = peter.include( alphamask ); §\C{// i is assigned 6}§ 2574 \end{cfa} 2575 2576 The ©exclude© operation 2577 \begin{cfa} 2578 int exclude( string &mask, int start = 1, occurrence occ = first ) 2579 \end{cfa} 2580 returns the position of the first or last character (depending on the occurrence indicator, which is either ©first© or ©last©) in the current string that does appear in the ©mask© string starting the search at position ©start©; 2581 hence it skips over characters in the current string that are excluded from (not in) in the ©mask© string. 2582 The characters in the current string do not have to be in the same order as the ©mask© string. 2583 If all the characters in the current string do NOT appear in the ©mask© string, the length of the current string plus one is returned, regardless of which occurrence is being searched for. 2584 A negative starting position is a specification from the right end of the string. 2585 \begin{cfa} 2586 i = peter.exclude( digitmask ); §\C{// i is assigned 6}§ 2587 i = ifstmt.exclude( strmask( punctuation ) ); §\C{// i is assigned 4}§ 2588 \end{cfa} 2589 2590 The ©includeStr© operation: 2591 \begin{cfa} 2592 string includeStr( strmask &mask, int start = 1, occurrence occ = first ) 2593 \end{cfa} 2594 returns the longest substring of leading or trailing characters (depending on the occurrence indicator, which is either ©first© or ©last©) of the current string that ARE included in the ©mask© string starting the search at position ©start©. 2595 A negative starting position is a specification from the right end of the string. 2596 \begin{cfa} 2597 s = peter.includeStr( alphamask ); §\C{// s is assigned "PETER"}§ 2598 s = ifstmt.includeStr( alphamask ); §\C{// s is assigned "IF"}§ 2599 s = peter.includeStr( digitmask ); §\C{// s is assigned ""}§ 2600 \end{cfa} 2601 2602 The ©excludeStr© operation: 2603 \begin{cfa} 2604 string excludeStr( strmask &mask, int start = 1, occurrence = first ) 2605 \end{cfa} 2606 returns the longest substring of leading or trailing characters (depending on the occurrence indicator, which is either ©first© or ©last©) of the current string that are excluded (NOT) in the ©mask© string starting the search at position ©start©. 2607 A negative starting position is a specification from the right end of the string. 2608 \begin{cfa} 2609 s = peter.excludeStr( digitmask); §\C{// s is assigned "PETER"}§ 2610 s = ifstmt.excludeStr( strmask( punctuation ) ); §\C{// s is assigned "IF "}§ 2611 s = peter.excludeStr( alphamask); §\C{// s is assigned ""}§ 2612 \end{cfa} 2613 2614 2615 \subsection{Miscellaneous} 2616 2617 The ©trim© operation 2618 \begin{cfa} 2619 string trim( string &mask, occurrence occ = first ) 2620 \end{cfa} 2621 returns a string in that is the longest substring of leading or trailing characters (depending on the occurrence indicator, which is either ©first© or ©last©) which ARE included in the ©mask© are removed. 2622 \begin{cfa} 2623 // remove leading blanks 2624 s = string( " ABC" ).trim( " " ); §\C{// s is assigned "ABC",}§ 2625 // remove trailing blanks 2626 s = string( "ABC " ).trim( " ", last ); §\C{// s is assigned "ABC",}§ 2627 \end{cfa} 2628 2629 The ©translate© operation 2630 \begin{cfa} 2631 string translate( string &from, string &to ) 2632 \end{cfa} 2633 returns a string that is the same length as the original string in which all occurrences of the characters that appear in the ©from© string have been translated into their corresponding character in the ©to© string. 2634 Translation is done on a character by character basis between the ©from© and ©to© strings; hence these two strings must be the same length. 2635 If a character in the original string does not appear in the ©from© string, then it simply appears as is in the resulting string. 2636 \begin{cfa} 2637 // upper to lower case 2638 peter = peter.translate( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" ); 2639 // peter is assigned "peter" 2640 s = ifstmt.translate( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" ); 2641 // ifstmt is assigned "if (a > b) {" 2642 // lower to upper case 2643 peter = peter.translate( "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); 2644 // peter is assigned "PETER" 2645 \end{cfa} 2646 2647 The ©replace© operation 2648 \begin{cfa} 2649 string replace( string &from, string &to ) 2650 \end{cfa} 2651 returns a string in which all occurrences of the ©from© string in the current string have been replaced by the ©to© string. 2652 \begin{cfa} 2653 s = peter.replace( "E", "XX" ); §\C{// s is assigned "PXXTXXR"}§ 2654 \end{cfa} 2655 The replacement is done left-to-right. 2656 When an instance of the ©from© string is found and changed to the ©to© string, it is NOT examined again for further replacement. 2657 2658 2659 \section{Returning N+1 on Failure} 2660 2661 Any of the string search routines can fail at some point during the search. 2662 When this happens it is necessary to return indicating the failure. 2663 Many string types in other languages use some special value to indicate the failure. 2664 This value is often 0 or -1 (PL/I returns 0). 2665 This section argues that a value of N+1, where N is the length of the base string in the search, is a more useful value to return. 2666 The index-of function in APL returns N+1. 2667 These are the boundary situations and are often overlooked when designing a string type. 2668 2669 The situation that can be optimized by returning N+1 is when a search is performed to find the starting location for a substring operation. 2670 For example, in a program that is extracting words from a text file, it is necessary to scan from left to right over whitespace until the first alphabetic character is found. 2671 \begin{cfa} 2672 line = line( line.exclude( alpha ) ); 2673 \end{cfa} 2674 If a text line contains all whitespaces, the exclude operation fails to find an alphabetic character. 2675 If ©exclude© returns 0 or -1, the result of the substring operation is unclear. 2676 Most string types generate an error, or clip the starting value to 1, resulting in the entire whitespace string being selected. 2677 If ©exclude© returns N+1, the starting position for the substring operation is beyond the end of the string leaving a null string. 2678 2679 The same situation occurs when scanning off a word. 2680 \begin{cfa} 2681 start = line.include(alpha); 2682 word = line(1, start - 1); 2683 \end{cfa} 2684 If the entire line is composed of a word, the include operation will fail to find a non-alphabetic character. 2685 In general, returning 0 or -1 is not an appropriate starting position for the substring, which must substring off the word leaving a null string. 2686 However, returning N+1 will substring off the word leaving a null string. 2687 2688 2689 \subsection{Input/Output Operators} 2690 2691 Both the \CC operators ©<<© and ©>>© are defined on type ©string©. 2692 However, input of a string value is different from input of a ©char *© value. 2693 When a string value is read, \emph{all} input characters from the current point in the input stream to either the end of line (©'\n'©) or the end of file are read. 2694 2695 2321 2696 \section{Enumeration} 2322 2697 … … 2332 2707 Hence, enums may be overloaded with variable, enum, and function names. 2333 2708 \begin{cfa} 2334 int Foo; $\C{// type/variable separate namespaces}$2709 int Foo; §\C{// type/variable separate namespaces}§ 2335 2710 enum Foo { Bar }; 2336 enum Goo { Bar }; $\C[1.75in]{// overload Foo.Bar}$2337 double Bar; $\C{// overload Foo.Bar, Goo.Bar}\CRT$2711 enum Goo { Bar }; §\C[1.75in]{// overload Foo.Bar}§ 2712 double Bar; §\C{// overload Foo.Bar, Goo.Bar}\CRT§ 2338 2713 \end{cfa} 2339 2714 An anonymous enumeration injects enums with specific values into a scope. … … 2408 2783 The following examples illustrate the difference between the enumeration type and the type of its enums. 2409 2784 \begin{cfa} 2410 Math m = PI; $\C[1.5in]{// allowed}$2411 double d = PI; $\C{// allowed, conversion to base type}$2412 m = E; $\C{// allowed}$2413 m = Alph; $\C{// {\color{red}disallowed}}$2414 m = 3.141597; $\C{// {\color{red}disallowed}}$2415 d = m; $\C{// allowed}$2416 d = Alph; $\C{// {\color{red}disallowed}}$2417 Letter l = A; $\C{// allowed}$2418 Greek g = Alph; $\C{// allowed}$2419 l = Alph; $\C{// allowed, conversion to base type}$2420 g = A; $\C{// {\color{red}disallowed}}\CRT$2785 Math m = PI; §\C[1.5in]{// allowed}§ 2786 double d = PI; §\C{// allowed, conversion to base type}§ 2787 m = E; §\C{// allowed}§ 2788 m = Alph; §\C{// {\color{red}disallowed}}§ 2789 m = 3.141597; §\C{// {\color{red}disallowed}}§ 2790 d = m; §\C{// allowed}§ 2791 d = Alph; §\C{// {\color{red}disallowed}}§ 2792 Letter l = A; §\C{// allowed}§ 2793 Greek g = Alph; §\C{// allowed}§ 2794 l = Alph; §\C{// allowed, conversion to base type}§ 2795 g = A; §\C{// {\color{red}disallowed}}\CRT§ 2421 2796 \end{cfa} 2422 2797 … … 2508 2883 \begin{cfa} 2509 2884 ®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) { 2510 $\emph{routine body}$2885 §\emph{routine body}§ 2511 2886 } 2512 2887 \end{cfa} … … 2519 2894 Declaration qualifiers can only appear at the start of a routine definition, \eg: 2520 2895 \begin{cfa} 2521 ®extern® [ int x ] g( int y ) { $\,$}2896 ®extern® [ int x ] g( int y ) {§\,§} 2522 2897 \end{cfa} 2523 2898 Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified; 2524 2899 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: 2525 2900 \begin{cfa} 2526 [ $\,$] g(); $\C{// no input or output parameters}$2527 [ void ] g( void ); $\C{// no input or output parameters}$2901 [§\,§] g(); §\C{// no input or output parameters}§ 2902 [ void ] g( void ); §\C{// no input or output parameters}§ 2528 2903 \end{cfa} 2529 2904 … … 2543 2918 \begin{cfa} 2544 2919 typedef int foo; 2545 int f( int (* foo) ); $\C{// foo is redefined as a parameter name}$2920 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§ 2546 2921 \end{cfa} 2547 2922 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. … … 2551 2926 C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg: 2552 2927 \begin{cfa} 2553 [ int ] f( * int, int * ); $\C{// returns an integer, accepts 2 pointers to integers}$2554 [ * int, int * ] f( int ); $\C{// returns 2 pointers to integers, accepts an integer}$2928 [ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§ 2929 [ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§ 2555 2930 \end{cfa} 2556 2931 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: 2557 2932 \begin{cfa} 2558 2933 #define ptoa( n, d ) int (*n)[ d ] 2559 int f( ptoa( p, 5 ) ) ... $\C{// expands to int f( int (*p)[ 5 ] )}$2560 [ int ] f( ptoa( p, 5 ) ) ... $\C{// expands to [ int ] f( int (*p)[ 5 ] )}$2934 int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§ 2935 [ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§ 2561 2936 \end{cfa} 2562 2937 Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms. … … 2580 2955 int z; 2581 2956 ... x = 0; ... y = z; ... 2582 ®return;® $\C{// implicitly return x, y}$2957 ®return;® §\C{// implicitly return x, y}§ 2583 2958 } 2584 2959 \end{cfa} … … 2590 2965 [ int x, int y ] f() { 2591 2966 ... 2592 } $\C{// implicitly return x, y}$2967 } §\C{// implicitly return x, y}§ 2593 2968 \end{cfa} 2594 2969 In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered. … … 2599 2974 [ int x, int y ] f( int, x, int y ) { 2600 2975 ... 2601 } $\C{// implicitly return x, y}$2976 } §\C{// implicitly return x, y}§ 2602 2977 \end{cfa} 2603 2978 This notation allows the compiler to eliminate temporary variables in nested routine calls. 2604 2979 \begin{cfa} 2605 [ int x, int y ] f( int, x, int y ); $\C{// prototype declaration}$2980 [ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§ 2606 2981 int a, b; 2607 2982 [a, b] = f( f( f( a, b ) ) ); … … 2617 2992 as well, parameter names are optional, \eg: 2618 2993 \begin{cfa} 2619 [ int x ] f (); $\C{// returning int with no parameters}$2620 [ * int ] g (int y); $\C{// returning pointer to int with int parameter}$2621 [ ] h ( int, char ); $\C{// returning no result with int and char parameters}$2622 [ * int, int ] j ( int ); $\C{// returning pointer to int and int, with int parameter}$2994 [ int x ] f (); §\C{// returning int with no parameters}§ 2995 [ * int ] g (int y); §\C{// returning pointer to int with int parameter}§ 2996 [ ] h ( int, char ); §\C{// returning no result with int and char parameters}§ 2997 [ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§ 2623 2998 \end{cfa} 2624 2999 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa). … … 2626 3001 \begin{cfa} 2627 3002 C : const double bar1(), bar2( int ), bar3( double ); 2628 $\CFA$: [const double] foo(), foo( int ), foo( double ) { return 3.0; }3003 §\CFA§: [const double] foo(), foo( int ), foo( double ) { return 3.0; } 2629 3004 \end{cfa} 2630 3005 \CFA allows the last routine in the list to define its body. … … 2641 3016 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 2642 3017 \begin{cfa} 2643 * [ int x ] () fp; $\C[2.25in]{// pointer to routine returning int with no parameters}$2644 * [ * int ] (int y) gp; $\C{// pointer to routine returning pointer to int with int parameter}$2645 * [ ] (int,char) hp; $\C{// pointer to routine returning no result with int and char parameters}$2646 * [ * int,int ] ( int ) jp; $\C{// pointer to routine returning pointer to int and int, with int parameter}\CRT$3018 * [ int x ] () fp; §\C[2.25in]{// pointer to routine returning int with no parameters}§ 3019 * [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§ 3020 * [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§ 3021 * [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}\CRT§ 2647 3022 \end{cfa} 2648 3023 While parameter names are optional, \emph{a routine name cannot be specified}; 2649 3024 for example, the following is incorrect: 2650 3025 \begin{cfa} 2651 * [ int x ] f () fp; $\C{// routine name "f" is not allowed}$3026 * [ int x ] f () fp; §\C{// routine name "f" is not allowed}§ 2652 3027 \end{cfa} 2653 3028 … … 2672 3047 whereas a named (keyword) call may be: 2673 3048 \begin{cfa} 2674 p( z : 3, x : 4, y : 7 ); $\C{// rewrite \(\Rightarrow\) p( 4, 7, 3 )}$3049 p( z : 3, x : 4, y : 7 ); §\C{// rewrite \(\Rightarrow\) p( 4, 7, 3 )}§ 2675 3050 \end{cfa} 2676 3051 Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters. … … 2689 3064 For example, the following routine prototypes and definition are all valid. 2690 3065 \begin{cfa} 2691 void p( int, int, int ); $\C{// equivalent prototypes}$3066 void p( int, int, int ); §\C{// equivalent prototypes}§ 2692 3067 void p( int x, int y, int z ); 2693 3068 void p( int y, int x, int z ); 2694 3069 void p( int z, int y, int x ); 2695 void p( int q, int r, int s ) {} $\C{// match with this definition}$3070 void p( int q, int r, int s ) {} §\C{// match with this definition}§ 2696 3071 \end{cfa} 2697 3072 Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming. … … 2705 3080 int f( int x, double y ); 2706 3081 2707 f( j : 3, i : 4 ); $\C{// 1st f}$2708 f( x : 7, y : 8.1 ); $\C{// 2nd f}$2709 f( 4, 5 ); $\C{// ambiguous call}$3082 f( j : 3, i : 4 ); §\C{// 1st f}§ 3083 f( x : 7, y : 8.1 ); §\C{// 2nd f}§ 3084 f( 4, 5 ); §\C{// ambiguous call}§ 2710 3085 \end{cfa} 2711 3086 However, named arguments compound routine resolution in conjunction with conversions: 2712 3087 \begin{cfa} 2713 f( i : 3, 5.7 ); $\C{// ambiguous call ?}$3088 f( i : 3, 5.7 ); §\C{// ambiguous call ?}§ 2714 3089 \end{cfa} 2715 3090 Depending on the cost associated with named arguments, this call could be resolvable or ambiguous. … … 2725 3100 the allowable positional calls are: 2726 3101 \begin{cfa} 2727 p(); $\C{// rewrite \(\Rightarrow\) p( 1, 2, 3 )}$2728 p( 4 ); $\C{// rewrite \(\Rightarrow\) p( 4, 2, 3 )}$2729 p( 4, 4 ); $\C{// rewrite \(\Rightarrow\) p( 4, 4, 3 )}$2730 p( 4, 4, 4 ); $\C{// rewrite \(\Rightarrow\) p( 4, 4, 4 )}$3102 p(); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 3 )}§ 3103 p( 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 2, 3 )}§ 3104 p( 4, 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 4, 3 )}§ 3105 p( 4, 4, 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 4, 4 )}§ 2731 3106 // empty arguments 2732 p( , 4, 4 ); $\C{// rewrite \(\Rightarrow\) p( 1, 4, 4 )}$2733 p( 4, , 4 ); $\C{// rewrite \(\Rightarrow\) p( 4, 2, 4 )}$2734 p( 4, 4, ); $\C{// rewrite \(\Rightarrow\) p( 4, 4, 3 )}$2735 p( 4, , ); $\C{// rewrite \(\Rightarrow\) p( 4, 2, 3 )}$2736 p( , 4, ); $\C{// rewrite \(\Rightarrow\) p( 1, 4, 3 )}$2737 p( , , 4 ); $\C{// rewrite \(\Rightarrow\) p( 1, 2, 4 )}$2738 p( , , ); $\C{// rewrite \(\Rightarrow\) p( 1, 2, 3 )}$3107 p( , 4, 4 ); §\C{// rewrite \(\Rightarrow\) p( 1, 4, 4 )}§ 3108 p( 4, , 4 ); §\C{// rewrite \(\Rightarrow\) p( 4, 2, 4 )}§ 3109 p( 4, 4, ); §\C{// rewrite \(\Rightarrow\) p( 4, 4, 3 )}§ 3110 p( 4, , ); §\C{// rewrite \(\Rightarrow\) p( 4, 2, 3 )}§ 3111 p( , 4, ); §\C{// rewrite \(\Rightarrow\) p( 1, 4, 3 )}§ 3112 p( , , 4 ); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 4 )}§ 3113 p( , , ); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 3 )}§ 2739 3114 \end{cfa} 2740 3115 Here the missing arguments are inserted from the default values in the parameter list. … … 2760 3135 Default values may only appear in a prototype versus definition context: 2761 3136 \begin{cfa} 2762 void p( int x, int y = 2, int z = 3 ); $\C{// prototype: allowed}$2763 void p( int, int = 2, int = 3 ); $\C{// prototype: allowed}$2764 void p( int x, int y = 2, int z = 3 ) {} $\C{// definition: not allowed}$3137 void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§ 3138 void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§ 3139 void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§ 2765 3140 \end{cfa} 2766 3141 The reason for this restriction is to allow separate compilation. … … 2777 3152 \begin{cfa} 2778 3153 p( int x, int y, int z, ... ); 2779 p( 1, 4, 5, 6, z : 3, y : 2 ); $\C{// assume p( /* positional */, ... , /* named */ );}$2780 p( 1, z : 3, y : 2, 4, 5, 6 ); $\C{// assume p( /* positional */, /* named */, ... );}$3154 p( 1, 4, 5, 6, z : 3, y : 2 ); §\C{// assume p( /* positional */, ... , /* named */ );}§ 3155 p( 1, z : 3, y : 2, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§ 2781 3156 \end{cfa} 2782 3157 In the first call, it is necessary for the programmer to conceptually rewrite the call, changing named arguments into positional, before knowing where the ellipse arguments begin. … … 2787 3162 \begin{cfa} 2788 3163 void p( int x, int y = 2, int z = 3... ); 2789 p( 1, 4, 5, 6, z : 3 ); $\C{// assume p( /* positional */, ... , /* named */ );}$2790 p( 1, z : 3, 4, 5, 6 ); $\C{// assume p( /* positional */, /* named */, ... );}$3164 p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§ 3165 p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§ 2791 3166 \end{cfa} 2792 3167 The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments; … … 2818 3193 Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as: 2819 3194 \begin{cfa} 2820 p( 1, /* default */, 5 ); $\C{// rewrite \(\Rightarrow\) p( 1, 2, 5 )}$3195 p( 1, /* default */, 5 ); §\C{// rewrite \(\Rightarrow\) p( 1, 2, 5 )}§ 2821 3196 \end{cfa} 2822 3197 … … 2831 3206 \begin{cfa} 2832 3207 struct { 2833 int f1; $\C{// named field}$2834 int f2 : 4; $\C{// named field with bit field size}$2835 int : 3; $\C{// unnamed field for basic type with bit field size}$2836 int ; $\C{// disallowed, unnamed field}$2837 int *; $\C{// disallowed, unnamed field}$2838 int (*)( int ); $\C{// disallowed, unnamed field}$3208 int f1; §\C{// named field}§ 3209 int f2 : 4; §\C{// named field with bit field size}§ 3210 int : 3; §\C{// unnamed field for basic type with bit field size}§ 3211 int ; §\C{// disallowed, unnamed field}§ 3212 int *; §\C{// disallowed, unnamed field}§ 3213 int (*)( int ); §\C{// disallowed, unnamed field}§ 2839 3214 }; 2840 3215 \end{cfa} … … 2844 3219 \begin{cfa} 2845 3220 struct { 2846 int , , ; $\C{// 3 unnamed fields}$3221 int , , ; §\C{// 3 unnamed fields}§ 2847 3222 } 2848 3223 \end{cfa} … … 2938 3313 const unsigned int size = 5; 2939 3314 int ia[size]; 2940 ... $\C{// assign values to array ia}$2941 qsort( ia, size ); $\C{// sort ascending order using builtin ?<?}$3315 ... §\C{// assign values to array ia}§ 3316 qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§ 2942 3317 { 2943 ®int ?<?( int x, int y ) { return x > y; }® $\C{// nested routine}$2944 qsort( ia, size ); $\C{// sort descending order by local redefinition}$3318 ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§ 3319 qsort( ia, size ); §\C{// sort descending order by local redefinition}§ 2945 3320 } 2946 3321 \end{cfa} … … 2950 3325 The following program in undefined in \CFA (and Indexc{gcc}) 2951 3326 \begin{cfa} 2952 [* [int]( int )] foo() { $\C{// int (* foo())( int )}$3327 [* [int]( int )] foo() { §\C{// int (* foo())( int )}§ 2953 3328 int ®i® = 7; 2954 3329 int bar( int p ) { 2955 ®i® += 1; $\C{// dependent on local variable}$3330 ®i® += 1; §\C{// dependent on local variable}§ 2956 3331 sout | ®i®; 2957 3332 } 2958 return bar; $\C{// undefined because of local dependence}$3333 return bar; §\C{// undefined because of local dependence}§ 2959 3334 } 2960 3335 int main() { 2961 * [int]( int ) fp = foo(); $\C{// int (* fp)( int )}$3336 * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§ 2962 3337 sout | fp( 3 ); 2963 3338 } … … 2972 3347 In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call. 2973 3348 \begin{cfa} 2974 f( ®2, x, 3 + i® ); $\C{// element list}$3349 f( ®2, x, 3 + i® ); §\C{// element list}§ 2975 3350 \end{cfa} 2976 3351 A list of elements is called a \newterm{tuple}, and is different from a \Index{comma expression}. … … 2987 3362 For example, consider C's \Indexc{div} function, which returns the quotient and remainder for a division of an integer value. 2988 3363 \begin{cfa} 2989 typedef struct { int quot, rem; } div_t; $\C[7cm]{// from include stdlib.h}$3364 typedef struct { int quot, rem; } div_t; §\C[7cm]{// from include stdlib.h}§ 2990 3365 div_t div( int num, int den ); 2991 div_t qr = div( 13, 5 ); $\C{// return quotient/remainder aggregate}$2992 printf( "%d %d\n", qr.quot, qr.rem ); $\C{// print quotient/remainder}$3366 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§ 3367 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§ 2993 3368 \end{cfa} 2994 3369 This approach requires a name for the return type and fields, where \Index{naming} is a common programming-language issue. … … 3000 3375 For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value. 3001 3376 \begin{cfa} 3002 double modf( double x, double * i ); $\C{// from include math.h}$3003 double intp, frac = modf( 13.5, &intp ); $\C{// return integral and fractional components}$3004 printf( "%g %g\n", intp, frac ); $\C{// print integral/fractional components}$3377 double modf( double x, double * i ); §\C{// from include math.h}§ 3378 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§ 3379 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§ 3005 3380 \end{cfa} 3006 3381 This approach requires allocating storage for the return values, which complicates the call site with a sequence of variable declarations leading to the call. … … 3029 3404 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. 3030 3405 \begin{cfa} 3031 void g( int, int ); $\C{// 1}$3032 void g( double, double ); $\C{// 2}$3033 g( div( 13, 5 ) ); $\C{// select 1}$3034 g( modf( 13.5 ) ); $\C{// select 2}$3406 void g( int, int ); §\C{// 1}§ 3407 void g( double, double ); §\C{// 2}§ 3408 g( div( 13, 5 ) ); §\C{// select 1}§ 3409 g( modf( 13.5 ) ); §\C{// select 2}§ 3035 3410 \end{cfa} 3036 3411 In this case, there are two overloaded ©g© routines. … … 3041 3416 The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call. 3042 3417 \begin{cfa} 3043 [ int, int ] div( int x, int y ); $\C{// from include stdlib}$3044 printf( "%d %d\n", div( 13, 5 ) ); $\C{// print quotient/remainder}$3045 3046 [ double, double ] modf( double x ); $\C{// from include math}$3047 printf( "%g %g\n", modf( 13.5 ) ); $\C{// print integral/fractional components}$3418 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§ 3419 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§ 3420 3421 [ double, double ] modf( double x ); §\C{// from include math}§ 3422 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§ 3048 3423 \end{cfa} 3049 3424 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. … … 3055 3430 \begin{cfa} 3056 3431 int quot, rem; 3057 [ quot, rem ] = div( 13, 5 ); $\C{// assign multiple variables}$3058 printf( "%d %d\n", quot, rem ); $\C{// print quotient/remainder}\CRT$3432 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§ 3433 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§ 3059 3434 \end{cfa} 3060 3435 Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call. … … 3085 3460 In \CFA, it is possible to overcome this restriction by declaring a \newterm{tuple variable}. 3086 3461 \begin{cfa} 3087 [int, int] ®qr® = div( 13, 5 ); $\C{// initialize tuple variable}$3088 printf( "%d %d\n", ®qr® ); $\C{// print quotient/remainder}$3462 [int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§ 3463 printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§ 3089 3464 \end{cfa} 3090 3465 It is now possible to match the multiple return-values to a single variable, in much the same way as \Index{aggregation}. … … 3092 3467 One way to access the individual components of a tuple variable is with assignment. 3093 3468 \begin{cfa} 3094 [ quot, rem ] = qr; $\C{// assign multiple variables}$3469 [ quot, rem ] = qr; §\C{// assign multiple variables}§ 3095 3470 \end{cfa} 3096 3471 … … 3115 3490 [int, double] * p; 3116 3491 3117 int y = x.0; $\C{// access int component of x}$3118 y = f().1; $\C{// access int component of f}$3119 p->0 = 5; $\C{// access int component of tuple pointed-to by p}$3120 g( x.1, x.0 ); $\C{// rearrange x to pass to g}$3121 double z = [ x, f() ].0.1; $\C{// access second component of first component of tuple expression}$3492 int y = x.0; §\C{// access int component of x}§ 3493 y = f().1; §\C{// access int component of f}§ 3494 p->0 = 5; §\C{// access int component of tuple pointed-to by p}§ 3495 g( x.1, x.0 ); §\C{// rearrange x to pass to g}§ 3496 double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§ 3122 3497 \end{cfa} 3123 3498 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. … … 3187 3562 double y; 3188 3563 [int, double] z; 3189 [y, x] = 3.14; $\C{// mass assignment}$3190 [x, y] = z; $\C{// multiple assignment}$3191 z = 10; $\C{// mass assignment}$3192 z = [x, y]; $\C{// multiple assignment}$3564 [y, x] = 3.14; §\C{// mass assignment}§ 3565 [x, y] = z; §\C{// multiple assignment}§ 3566 z = 10; §\C{// mass assignment}§ 3567 z = [x, y]; §\C{// multiple assignment}§ 3193 3568 \end{cfa} 3194 3569 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. … … 3198 3573 \begin{cfa} 3199 3574 [ int, int ] x, y, z; 3200 [ x, y ] = z; $\C{// multiple assignment, invalid 4 != 2}$3575 [ x, y ] = z; §\C{// multiple assignment, invalid 4 != 2}§ 3201 3576 \end{cfa} 3202 3577 Multiple assignment assigns $R_i$ to $L_i$ for each $i$. … … 3234 3609 double c, d; 3235 3610 [ void ] f( [ int, int ] ); 3236 f( [ c, a ] = [ b, d ] = 1.5 ); $\C{// assignments in parameter list}$3611 f( [ c, a ] = [ b, d ] = 1.5 ); §\C{// assignments in parameter list}§ 3237 3612 \end{cfa} 3238 3613 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. … … 3247 3622 \begin{cfa} 3248 3623 struct S; 3249 void ?{}(S *); $\C{// (1)}$3250 void ?{}(S *, int); $\C{// (2)}$3251 void ?{}(S * double); $\C{// (3)}$3252 void ?{}(S *, S); $\C{// (4)}$3253 3254 [S, S] x = [3, 6.28]; $\C{// uses (2), (3), specialized constructors}$3255 [S, S] y; $\C{// uses (1), (1), default constructor}$3256 [S, S] z = x.0; $\C{// uses (4), (4), copy constructor}$3624 void ?{}(S *); §\C{// (1)}§ 3625 void ?{}(S *, int); §\C{// (2)}§ 3626 void ?{}(S * double); §\C{// (3)}§ 3627 void ?{}(S *, S); §\C{// (4)}§ 3628 3629 [S, S] x = [3, 6.28]; §\C{// uses (2), (3), specialized constructors}§ 3630 [S, S] y; §\C{// uses (1), (1), default constructor}§ 3631 [S, S] z = x.0; §\C{// uses (4), (4), copy constructor}§ 3257 3632 \end{cfa} 3258 3633 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)©. … … 3295 3670 A member-access tuple may be used anywhere a tuple can be used, \eg: 3296 3671 \begin{cfa} 3297 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; $\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}$3298 f( s.[ y, z ] ); $\C{// equivalent to f( s.y, s.z )}$3672 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§ 3673 f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§ 3299 3674 \end{cfa} 3300 3675 Note, the fields appearing in a record-field tuple may be specified in any order; … … 3306 3681 void f( double, long ); 3307 3682 3308 f( x.[ 0, 3 ] ); $\C{// f( x.0, x.3 )}$3309 x.[ 0, 1 ] = x.[ 1, 0 ]; $\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}$3683 f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§ 3684 x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§ 3310 3685 [ long, int, long ] y = x.[ 2, 0, 2 ]; 3311 3686 \end{cfa} … … 3324 3699 \begin{cfa} 3325 3700 [ int, float, double ] f(); 3326 [ double, float ] x = f().[ 2, 1 ]; $\C{// f() called once}$3701 [ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§ 3327 3702 \end{cfa} 3328 3703 … … 3337 3712 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. 3338 3713 \begin{cfa} 3339 int f(); $\C{// (1)}$3340 double f(); $\C{// (2)}$3341 3342 f(); $\C{// ambiguous - (1),(2) both equally viable}$3343 (int)f(); $\C{// choose (2)}$3714 int f(); §\C{// (1)}§ 3715 double f(); §\C{// (2)}§ 3716 3717 f(); §\C{// ambiguous - (1),(2) both equally viable}§ 3718 (int)f(); §\C{// choose (2)}§ 3344 3719 \end{cfa} 3345 3720 Since casting is a fundamental operation in \CFA, casts need to be given a meaningful interpretation in the context of tuples. … … 3349 3724 void g(); 3350 3725 3351 (void)f(); $\C{// valid, ignore results}$3352 (int)g(); $\C{// invalid, void cannot be converted to int}$3726 (void)f(); §\C{// valid, ignore results}§ 3727 (int)g(); §\C{// invalid, void cannot be converted to int}§ 3353 3728 3354 3729 struct A { int x; }; 3355 (struct A)f(); $\C{// invalid, int cannot be converted to A}$3730 (struct A)f(); §\C{// invalid, int cannot be converted to A}§ 3356 3731 \end{cfa} 3357 3732 In C, line 4 is a valid cast, which calls ©f© and discards its result. … … 3369 3744 [int, [int, int], int] g(); 3370 3745 3371 ([int, double])f(); $\C{// (1) valid}$3372 ([int, int, int])g(); $\C{// (2) valid}$3373 ([void, [int, int]])g(); $\C{// (3) valid}$3374 ([int, int, int, int])g(); $\C{// (4) invalid}$3375 ([int, [int, int, int]])g(); $\C{// (5) invalid}$3746 ([int, double])f(); §\C{// (1) valid}§ 3747 ([int, int, int])g(); §\C{// (2) valid}§ 3748 ([void, [int, int]])g(); §\C{// (3) valid}§ 3749 ([int, int, int, int])g(); §\C{// (4) invalid}§ 3750 ([int, [int, int, int]])g(); §\C{// (5) invalid}§ 3376 3751 \end{cfa} 3377 3752 … … 3433 3808 void f([int, int], int, int); 3434 3809 3435 f([0, 0], 0, 0); $\C{// no cost}$3436 f(0, 0, 0, 0); $\C{// cost for structuring}$3437 f([0, 0,], [0, 0]); $\C{// cost for flattening}$3438 f([0, 0, 0], 0); $\C{// cost for flattening and structuring}$3810 f([0, 0], 0, 0); §\C{// no cost}§ 3811 f(0, 0, 0, 0); §\C{// cost for structuring}§ 3812 f([0, 0,], [0, 0]); §\C{// cost for flattening}§ 3813 f([0, 0, 0], 0); §\C{// cost for flattening and structuring}§ 3439 3814 \end{cfa} 3440 3815 … … 3500 3875 [ unsigned int, char ] 3501 3876 [ double, double, double ] 3502 [ * int, int * ] $\C{// mix of CFA and ANSI}$3877 [ * int, int * ] §\C{// mix of CFA and ANSI}§ 3503 3878 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ] 3504 3879 \end{cfa} … … 3507 3882 Examples of declarations using tuple types are: 3508 3883 \begin{cfa} 3509 [ int, int ] x; $\C{// 2 element tuple, each element of type int}$3510 * [ char, char ] y; $\C{// pointer to a 2 element tuple}$3884 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§ 3885 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§ 3511 3886 [ [ int, int ] ] z ([ int, int ]); 3512 3887 \end{cfa} … … 3525 3900 [ int, int ] w1; 3526 3901 [ int, int, int ] w2; 3527 [ void ] f (int, int, int); $\C{// three input parameters of type int}$3528 [ void ] g ([ int, int, int ]); $\C{3 element tuple as input}$3902 [ void ] f (int, int, int); §\C{// three input parameters of type int}§ 3903 [ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§ 3529 3904 f( [ 1, 2, 3 ] ); 3530 3905 f( w1, 3 ); … … 3607 3982 [ int, int, int, int ] w = [ 1, 2, 3, 4 ]; 3608 3983 int x = 5; 3609 [ x, w ] = [ w, x ]; $\C{// all four tuple coercions}$3984 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§ 3610 3985 \end{cfa} 3611 3986 Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values; … … 3697 4072 both these examples produce indeterminate results: 3698 4073 \begin{cfa} 3699 f( x++, x++ ); $\C{// C routine call with side effects in arguments}$3700 [ v1, v2 ] = [ x++, x++ ]; $\C{// side effects in right-hand side of multiple assignment}$4074 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§ 4075 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in right-hand side of multiple assignment}§ 3701 4076 \end{cfa} 3702 4077 … … 3797 4172 \begin{cfa} 3798 4173 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ]; 3799 sout | t1 | t2; $\C{// print tuples}$4174 sout | t1 | t2; §\C{// print tuples}§ 3800 4175 \end{cfa} 3801 4176 \begin{cfa}[showspaces=true,aboveskip=0pt] … … 3881 4256 3882 4257 int main( int argc, char * argv[] ) { 3883 ®ifstream® in = stdin; $\C{// copy default files}$4258 ®ifstream® in = stdin; §\C{// copy default files}§ 3884 4259 ®ofstream® out = stdout; 3885 4260 … … 3887 4262 choose ( argc ) { 3888 4263 case 2, 3: 3889 ®open®( in, argv[1] ); $\C{// open input file first as output creates file}$3890 if ( argc == 3 ) ®open®( out, argv[2] ); $\C{// do not create output unless input opens}$3891 case 1: ; $\C{// use default files}$4264 ®open®( in, argv[1] ); §\C{// open input file first as output creates file}§ 4265 if ( argc == 3 ) ®open®( out, argv[2] ); §\C{// do not create output unless input opens}§ 4266 case 1: ; §\C{// use default files}§ 3892 4267 default: 3893 4268 ®exit® | "Usage" | argv[0] | "[ input-file (default stdin) " 3894 4269 "[ output-file (default stdout) ] ]"; 3895 4270 } // choose 3896 } catch( ®open_failure® * ex; ex->istream == &in ) { $\C{// input file errors}$4271 } catch( ®open_failure® * ex; ex->istream == &in ) { §\C{// input file errors}§ 3897 4272 ®exit® | "Unable to open input file" | argv[1]; 3898 } catch( ®open_failure® * ex; ex->ostream == &out ) { $\C{// output file errors}$3899 ®close®( in ); $\C{// optional}$4273 } catch( ®open_failure® * ex; ex->ostream == &out ) { §\C{// output file errors}§ 4274 ®close®( in ); §\C{// optional}§ 3900 4275 ®exit® | "Unable to open output file" | argv[2]; 3901 4276 } // try 3902 4277 3903 out | nlOff; $\C{// turn off auto newline}$3904 in | nlOn; $\C{// turn on reading newline}$4278 out | nlOff; §\C{// turn off auto newline}§ 4279 in | nlOn; §\C{// turn on reading newline}§ 3905 4280 char ch; 3906 for () { $\C{// read/write characters}$4281 for () { §\C{// read/write characters}§ 3907 4282 in | ch; 3908 if ( eof( in ) ) break; $\C{// eof ?}$4283 if ( eof( in ) ) break; §\C{// eof ?}§ 3909 4284 out | ch; 3910 4285 } // for … … 3953 4328 // *********************************** ofstream *********************************** 3954 4329 3955 bool fail( ofstream & ); $\indexc{fail}\index{ofstream@©ofstream©!©fail©}$3956 void clear( ofstream & ); $\indexc{clear}\index{ofstream@©ofstream©!©clear©}$3957 int flush( ofstream & ); $\indexc{flush}\index{ofstream@©ofstream©!©flush©}$3958 void open( ofstream &, const char name[], const char mode[] = "w" ); $\indexc{open}\index{ofstream@©ofstream©!©open©}$3959 void close( ofstream & ); $\indexc{close}\index{ofstream@©ofstream©!©close©}$3960 ofstream & write( ofstream &, const char data[], size_t size ); $\indexc{write}\index{ofstream@©ofstream©!©write©}$3961 3962 void ?{}( ofstream & ); $\index{ofstream@©ofstream©!©?{}©}$4330 bool fail( ofstream & );§\indexc{fail}\index{ofstream@©ofstream©!©fail©}§ 4331 void clear( ofstream & );§\indexc{clear}\index{ofstream@©ofstream©!©clear©}§ 4332 int flush( ofstream & );§\indexc{flush}\index{ofstream@©ofstream©!©flush©}§ 4333 void open( ofstream &, const char name[], const char mode[] = "w" );§\indexc{open}\index{ofstream@©ofstream©!©open©}§ 4334 void close( ofstream & );§\indexc{close}\index{ofstream@©ofstream©!©close©}§ 4335 ofstream & write( ofstream &, const char data[], size_t size );§\indexc{write}\index{ofstream@©ofstream©!©write©}§ 4336 4337 void ?{}( ofstream & );§\index{ofstream@©ofstream©!©?{}©}§ 3963 4338 void ?{}( ofstream &, const char name[], const char mode[] = "w" ); 3964 void ^?{}( ofstream & ); $\index{ofstream@©ofstream©!©^?{}©}$4339 void ^?{}( ofstream & );§\index{ofstream@©ofstream©!©^?{}©}§ 3965 4340 3966 4341 // *********************************** ifstream *********************************** 3967 4342 3968 bool fail( ifstream & is ); $\indexc{fail}\index{ifstream@©ifstream©!©fail©}$3969 void clear( ifstream & ); $\indexc{clear}\index{ifstream@©ifstream©!©clear©}$3970 bool eof( ifstream & is ); $\indexc{eof}\index{ifstream@©ifstream©!©eof©}$3971 void open( ifstream & is, const char name[], const char mode[] = "r" ); $\indexc{open}\index{ifstream@©ifstream©!©open©}$3972 void close( ifstream & is ); $\indexc{close}\index{ifstream@©ifstream©!©close©}$3973 ifstream & read( ifstream & is, char data[], size_t size ); $\indexc{read}\index{ifstream@©ifstream©!©read©}$3974 ifstream & ungetc( ifstream & is, char c ); $\indexc{unget}\index{ifstream@©ifstream©!©unget©}$3975 3976 void ?{}( ifstream & is ); $\index{ifstream@©ifstream©!©?{}©}$4343 bool fail( ifstream & is );§\indexc{fail}\index{ifstream@©ifstream©!©fail©}§ 4344 void clear( ifstream & );§\indexc{clear}\index{ifstream@©ifstream©!©clear©}§ 4345 bool eof( ifstream & is );§\indexc{eof}\index{ifstream@©ifstream©!©eof©}§ 4346 void open( ifstream & is, const char name[], const char mode[] = "r" );§\indexc{open}\index{ifstream@©ifstream©!©open©}§ 4347 void close( ifstream & is );§\indexc{close}\index{ifstream@©ifstream©!©close©}§ 4348 ifstream & read( ifstream & is, char data[], size_t size );§\indexc{read}\index{ifstream@©ifstream©!©read©}§ 4349 ifstream & ungetc( ifstream & is, char c );§\indexc{unget}\index{ifstream@©ifstream©!©unget©}§ 4350 4351 void ?{}( ifstream & is );§\index{ifstream@©ifstream©!©?{}©}§ 3977 4352 void ?{}( ifstream & is, const char name[], const char mode[] = "r" ); 3978 void ^?{}( ifstream & is ); $\index{ifstream@©ifstream©!©^?{}©}$4353 void ^?{}( ifstream & is );§\index{ifstream@©ifstream©!©^?{}©}§ 3979 4354 \end{cfa} 3980 4355 \caption{Stream Functions} … … 4063 4438 The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 4064 4439 \begin{cfa}[belowskip=0pt] 4065 sepSet( sout, ", $\LstStringStyle{\textdollar}$" ); $\C{// set separator from " " to ", \$"}$4440 sepSet( sout, ", $\LstStringStyle{\textdollar}$" ); §\C{// set separator from " " to ", \$"}§ 4066 4441 sout | 1 | 2 | 3 | " \"" | ®sepVal® | "\""; 4067 4442 \end{cfa} … … 4070 4445 \end{cfa} 4071 4446 \begin{cfa}[belowskip=0pt] 4072 sepSet( sout, " " ); $\C{// reset separator to " "}$4447 sepSet( sout, " " ); §\C{// reset separator to " "}§ 4073 4448 sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\""; 4074 4449 \end{cfa} … … 4078 4453 ©sepGet© can be used to store a separator and then restore it: 4079 4454 \begin{cfa}[belowskip=0pt] 4080 char store[®sepSize®]; $\C{// sepSize is the maximum separator size}$4081 strcpy( store, sepGet( sout ) ); $\C{// copy current separator}$4082 sepSet( sout, "_" ); $\C{// change separator to underscore}$4455 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§ 4456 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§ 4457 sepSet( sout, "_" ); §\C{// change separator to underscore}§ 4083 4458 sout | 1 | 2 | 3; 4084 4459 \end{cfa} … … 4087 4462 \end{cfa} 4088 4463 \begin{cfa}[belowskip=0pt] 4089 sepSet( sout, store ); $\C{// change separator back to original}$4464 sepSet( sout, store ); §\C{// change separator back to original}§ 4090 4465 sout | 1 | 2 | 3; 4091 4466 \end{cfa} … … 4098 4473 The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 4099 4474 \begin{cfa}[belowskip=0pt] 4100 sepSetTuple( sout, " " ); $\C{// set tuple separator from ", " to " "}$4475 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§ 4101 4476 sout | t1 | t2 | " \"" | ®sepTupleVal® | "\""; 4102 4477 \end{cfa} … … 4105 4480 \end{cfa} 4106 4481 \begin{cfa}[belowskip=0pt] 4107 sepSetTuple( sout, ", " ); $\C{// reset tuple separator to ", "}$4482 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§ 4108 4483 sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\""; 4109 4484 \end{cfa} … … 4116 4491 \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} and \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} globally toggle printing the separator. 4117 4492 \begin{cfa}[belowskip=0pt] 4118 sout | ®sepOff® | 1 | 2 | 3; $\C{// turn off implicit separator}$4493 sout | ®sepOff® | 1 | 2 | 3; §\C{// turn off implicit separator}§ 4119 4494 \end{cfa} 4120 4495 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4122 4497 \end{cfa} 4123 4498 \begin{cfa}[belowskip=0pt] 4124 sout | ®sepOn® | 1 | 2 | 3; $\C{// turn on implicit separator}$4499 sout | ®sepOn® | 1 | 2 | 3; §\C{// turn on implicit separator}§ 4125 4500 \end{cfa} 4126 4501 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4131 4506 \Indexc{sep}\index{manipulator!sep@©sep©} and \Indexc{nosep}\index{manipulator!nosep@©nosep©} locally toggle printing the separator with respect to the next printed item, and then return to the global separator setting. 4132 4507 \begin{cfa}[belowskip=0pt] 4133 sout | 1 | ®nosep® | 2 | 3; $\C{// turn off implicit separator for the next item}$4508 sout | 1 | ®nosep® | 2 | 3; §\C{// turn off implicit separator for the next item}§ 4134 4509 \end{cfa} 4135 4510 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4137 4512 \end{cfa} 4138 4513 \begin{cfa}[belowskip=0pt] 4139 sout | sepOff | 1 | ®sep® | 2 | 3; $\C{// turn on implicit separator for the next item}$4514 sout | sepOff | 1 | ®sep® | 2 | 3; §\C{// turn on implicit separator for the next item}§ 4140 4515 \end{cfa} 4141 4516 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4144 4519 The tuple separator also responses to being turned on and off. 4145 4520 \begin{cfa}[belowskip=0pt] 4146 sout | t1 | ®nosep® | t2; $\C{// turn off implicit separator for the next item}$4521 sout | t1 | ®nosep® | t2; §\C{// turn off implicit separator for the next item}§ 4147 4522 \end{cfa} 4148 4523 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4152 4527 Use ©sep© to accomplish this functionality. 4153 4528 \begin{cfa}[belowskip=0pt] 4154 sout | ®sep® | 1 | 2 | 3 | ®sep®; $\C{// sep does nothing at start/end of line}$4529 sout | ®sep® | 1 | 2 | 3 | ®sep®; §\C{// sep does nothing at start/end of line}§ 4155 4530 \end{cfa} 4156 4531 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4158 4533 \end{cfa} 4159 4534 \begin{cfa}[belowskip=0pt] 4160 sout | ®sepVal® | 1 | 2 | 3 | ®sepVal® ; $\C{// use sepVal to print separator at start/end of line}$4535 sout | ®sepVal® | 1 | 2 | 3 | ®sepVal® ; §\C{// use sepVal to print separator at start/end of line}§ 4161 4536 \end{cfa} 4162 4537 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4197 4572 \Indexc{nl}\index{manipulator!nl@©nl©} inserts a newline. 4198 4573 \begin{cfa} 4199 sout | ®nl®; $\C{// only print newline}$4200 sout | 2; $\C{// implicit newline}$4201 sout | 3 | ®nl® | 4 | ®nl®; $\C{// terminating nl merged with implicit newline}$4202 sout | 5 | ®nl® | ®nl®; $\C{// again terminating nl merged with implicit newline}$4203 sout | 6; $\C{// implicit newline}$4574 sout | ®nl®; §\C{// only print newline}§ 4575 sout | 2; §\C{// implicit newline}§ 4576 sout | 3 | ®nl® | 4 | ®nl®; §\C{// terminating nl merged with implicit newline}§ 4577 sout | 5 | ®nl® | ®nl®; §\C{// again terminating nl merged with implicit newline}§ 4578 sout | 6; §\C{// implicit newline}§ 4204 4579 4205 4580 2 … … 4648 5023 ®mutex( sout )® { 4649 5024 sout | 1; 4650 ®mutex( sout ) sout® | 2 | 3; $\C{// unnecessary, but ok because of recursive lock}$5025 ®mutex( sout ) sout® | 2 | 3; §\C{// unnecessary, but ok because of recursive lock}§ 4651 5026 sout | 4; 4652 5027 } // implicitly release sout lock … … 4660 5035 int x, y, z, w; 4661 5036 sin | x; 4662 ®mutex( sin )® sin | y | z; $\C{// unnecessary, but ok because of recursive lock}$5037 ®mutex( sin )® sin | y | z; §\C{// unnecessary, but ok because of recursive lock}§ 4663 5038 sin | w; 4664 5039 } // implicitly release sin lock … … 4669 5044 \Textbf{WARNING:} The general problem of \Index{nested locking} can occur if routines are called in an I/O sequence that block, \eg: 4670 5045 \begin{cfa} 4671 ®mutex( sout )® sout | "data:" | rtn( mon ); $\C{// mutex call on monitor}$5046 ®mutex( sout )® sout | "data:" | rtn( mon ); §\C{// mutex call on monitor}§ 4672 5047 \end{cfa} 4673 5048 If the thread executing the I/O expression blocks in the monitor with the ©sout© lock, other threads writing to ©sout© also block until the thread holding the lock is unblocked and releases it. … … 4687 5062 \begin{cfa} 4688 5063 12®,®345®.®123 $\C[1.25in]{// comma separator, period decimal-point}$ 4689 12®.®345®,®123 $\C{// period separator, comma decimal-point}$4690 12$\Sp$345®,®123®.® $\C{// space separator, comma decimal-point, period terminator}\CRT$5064 12®.®345®,®123 §\C{// period separator, comma decimal-point}§ 5065 12$\Sp$345®,®123®.® §\C{// space separator, comma decimal-point, period terminator}\CRT§ 4691 5066 \end{cfa} 4692 5067 A locale is selected with function ©setlocale©, and the corresponding locale package \emph{must} be installed on the underlying system; … … 4699 5074 \begin{cfa} 4700 5075 #include <fstream.hfa> 4701 #include <locale.h> $\C{// setlocale}$4702 #include <stdlib.h> $\C{// getenv}$5076 #include <locale.h> §\C{// setlocale}§ 5077 #include <stdlib.h> §\C{// getenv}§ 4703 5078 4704 5079 int main() { … … 4772 5147 int main() { 4773 5148 enum { size = 256 }; 4774 char buf[size]; $\C{// output buffer}$4775 ®ostrstream osstr = { buf, size };® $\C{// bind output buffer/size}$5149 char buf[size]; §\C{// output buffer}§ 5150 ®ostrstream osstr = { buf, size };® §\C{// bind output buffer/size}§ 4776 5151 int i = 3, j = 5, k = 7; 4777 5152 double x = 12345678.9, y = 98765.4321e-11; 4778 5153 4779 5154 osstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)) | "abc"; 4780 write( osstr ); $\C{// write string to stdout}$4781 printf( "%s", buf ); $\C{// same lines of output}$5155 write( osstr ); §\C{// write string to stdout}§ 5156 printf( "%s", buf ); §\C{// same lines of output}§ 4782 5157 sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)) | "abc"; 4783 5158 4784 char buf2[] = "12 14 15 3.5 7e4 abc"; $\C{// input buffer}$5159 char buf2[] = "12 14 15 3.5 7e4 abc"; §\C{// input buffer}§ 4785 5160 ®istrstream isstr = { buf2 };® 4786 5161 char s[10]; … … 4934 5309 // Subsequent arguments can be specified for initialization 4935 5310 4936 void ?{}( Widget & w ) { $\C{// default constructor}$5311 void ?{}( Widget & w ) { §\C{// default constructor}§ 4937 5312 w.id = -1; 4938 5313 w.size = 0.0; … … 4948 5323 4949 5324 // ^?{} is the destructor operator identifier 4950 void ^?{}( Widget & w ) { $\C{// destructor}$5325 void ^?{}( Widget & w ) { §\C{// destructor}§ 4951 5326 w.id = 0; 4952 5327 w.size = 0.0; … … 4957 5332 } 4958 5333 4959 Widget baz; $\C{// reserve space only}$4960 Widget foo{}; $\C{// calls default constructor}$4961 Widget bar{ 23, 2.45 }; $\C{// calls constructor with values}$4962 baz{ 24, 0.91 }; $\C{// calls constructor with values}$4963 ?{}( baz, 24, 0.91 ); $\C{// explicit call to constructor}$4964 ^?{} (bar ); $\C{// explicit call to destructor}$5334 Widget baz; §\C{// reserve space only}§ 5335 Widget foo{}; §\C{// calls default constructor}§ 5336 Widget bar{ 23, 2.45 }; §\C{// calls constructor with values}§ 5337 baz{ 24, 0.91 }; §\C{// calls constructor with values}§ 5338 ?{}( baz, 24, 0.91 ); §\C{// explicit call to constructor}§ 5339 ^?{} (bar ); §\C{// explicit call to destructor}§ 4965 5340 \end{cfa} 4966 5341 \caption{Constructors and Destructors} … … 5480 5855 5481 5856 ®coroutine® Fibonacci { 5482 int fn; $\C{// used for communication}$5857 int fn; §\C{// used for communication}§ 5483 5858 }; 5484 5859 5485 void main( Fibonacci & fib ) with( fib ) { $\C{// called on first resume}$5486 int fn1, fn2; $\C{// retained between resumes}$5487 fn = 0; fn1 = fn; $\C{// 1st case}$5488 ®suspend;® $\C{// restart last resume}$5489 fn = 1; fn2 = fn1; fn1 = fn; $\C{// 2nd case}$5490 ®suspend;® $\C{// restart last resume}$5860 void main( Fibonacci & fib ) with( fib ) { §\C{// called on first resume}§ 5861 int fn1, fn2; §\C{// retained between resumes}§ 5862 fn = 0; fn1 = fn; §\C{// 1st case}§ 5863 ®suspend;® §\C{// restart last resume}§ 5864 fn = 1; fn2 = fn1; fn1 = fn; §\C{// 2nd case}§ 5865 ®suspend;® §\C{// restart last resume}§ 5491 5866 for () { 5492 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; $\C{// general case}$5493 ®suspend;® $\C{// restart last resume}$5867 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; §\C{// general case}§ 5868 ®suspend;® §\C{// restart last resume}§ 5494 5869 } 5495 5870 } 5496 5871 int next( Fibonacci & fib ) with( fib ) { 5497 ®resume( fib );® $\C{// restart last suspend}$5872 ®resume( fib );® §\C{// restart last suspend}§ 5498 5873 return fn; 5499 5874 } 5500 5875 int main() { 5501 5876 Fibonacci f1, f2; 5502 for ( 10 ) { $\C{// print N Fibonacci values}$5877 for ( 10 ) { §\C{// print N Fibonacci values}§ 5503 5878 sout | next( f1 ) | next( f2 ); 5504 5879 } … … 5538 5913 int inc( AtomicCnt & ®mutex® c, int inc = 1 ) with(c) { return counter += inc; } 5539 5914 int dec( AtomicCnt & ®mutex® c, int dec = 1 ) with(c) { return counter -= dec; } 5540 forall( ostype & | ostream( ostype ) ) { $\C{// print any stream}$5915 forall( ostype & | ostream( ostype ) ) { §\C{// print any stream}§ 5541 5916 ostype & ?|?( ostype & os, AtomicCnt c ) { return os | c.counter; } 5542 5917 void ?|?( ostype & os, AtomicCnt c ) { (ostype &)(os | c.counter); ends( os ); } 5543 5918 } 5544 5919 5545 AtomicCnt global; $\C{// shared}$5920 AtomicCnt global; §\C{// shared}§ 5546 5921 5547 5922 thread MyThread {}; … … 5554 5929 int main() { 5555 5930 enum { Threads = 4 }; 5556 processor p[Threads - 1]; $\C{// + starting processor}$5931 processor p[Threads - 1]; §\C{// + starting processor}§ 5557 5932 { 5558 5933 MyThread t[Threads]; 5559 5934 } 5560 sout | global; $\C{// print 0}$5935 sout | global; §\C{// print 0}§ 5561 5936 } 5562 5937 \end{cfa} … … 7031 7406 In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as: 7032 7407 \begin{cfa} 7033 *?$\Sp$*? $\C{// dereference operator, dereference operator}$7034 *$\Sp$?*? $\C{// dereference, multiplication operator}$7408 *?$\Sp$*? §\C{// dereference operator, dereference operator}§ 7409 *$\Sp$?*? §\C{// dereference, multiplication operator}§ 7035 7410 \end{cfa} 7036 7411 By default, the first interpretation is selected, which does not yield a meaningful parse. … … 7084 7459 \eg: 7085 7460 \begin{cfa} 7086 x; $\C{// int x}$7087 *y; $\C{// int *y}$7088 f( p1, p2 ); $\C{// int f( int p1, int p2 );}$7089 g( p1, p2 ) int p1, p2; $\C{// int g( int p1, int p2 );}$7461 x; §\C{// int x}§ 7462 *y; §\C{// int *y}§ 7463 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 7464 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 7090 7465 \end{cfa} 7091 7466 \CFA continues to support K\&R routine definitions: 7092 7467 \begin{cfa} 7093 f( a, b, c ) $\C{// default int return}$7094 int a, b; char c $\C{// K\&R parameter declarations}$7468 f( a, b, c ) §\C{// default int return}§ 7469 int a, b; char c §\C{// K\&R parameter declarations}§ 7095 7470 { 7096 7471 ... … … 7111 7486 int rtn( int i ); 7112 7487 int rtn( char c ); 7113 rtn( 'x' ); $\C{// programmer expects 2nd rtn to be called}$7488 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 7114 7489 \end{cfa} 7115 7490 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. … … 7133 7508 \item[Change:] make string literals ©const©: 7134 7509 \begin{cfa} 7135 char * p = "abc"; $\C{// valid in C, deprecated in \CFA}$7136 char * q = expr ? "abc" : "de"; $\C{// valid in C, invalid in \CFA}$7510 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 7511 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 7137 7512 \end{cfa} 7138 7513 The type of a string literal is changed from ©[] char© to ©const [] char©. … … 7141 7516 \begin{cfa} 7142 7517 char * p = "abc"; 7143 p[0] = 'w'; $\C{// segment fault or change constant literal}$7518 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 7144 7519 \end{cfa} 7145 7520 The same problem occurs when passing a string literal to a routine that changes its argument. … … 7153 7528 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 7154 7529 \begin{cfa} 7155 int i; $\C{// forward definition}$7156 int *j = ®&i®; $\C{// forward reference, valid in C, invalid in \CFA}$7157 int i = 0; $\C{// definition}$7530 int i; §\C{// forward definition}§ 7531 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 7532 int i = 0; §\C{// definition}§ 7158 7533 \end{cfa} 7159 7534 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. … … 7161 7536 \begin{cfa} 7162 7537 struct X { int i; struct X *next; }; 7163 static struct X a; $\C{// forward definition}$7164 static struct X b = { 0, ®&a® }; $\C{// forward reference, valid in C, invalid in \CFA}$7165 static struct X a = { 1, &b }; $\C{// definition}$7538 static struct X a; §\C{// forward definition}§ 7539 static struct X b = { 0, ®&a® };§\C{// forward reference, valid in C, invalid in \CFA}§ 7540 static struct X a = { 1, &b }; §\C{// definition}§ 7166 7541 \end{cfa} 7167 7542 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types. … … 7178 7553 struct Person { 7179 7554 enum ®Colour® { R, G, B }; $\C[7cm]{// nested type}$ 7180 struct Face { $\C{// nested type}$7181 ®Colour® Eyes, Hair; $\C{// type defined outside (1 level)}$7555 struct Face { §\C{// nested type}§ 7556 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 7182 7557 }; 7183 ®.Colour® shirt; $\C{// type defined outside (top level)}$7184 ®Colour® pants; $\C{// type defined same level}$7185 Face looks[10]; $\C{// type defined same level}$7558 ®.Colour® shirt; §\C{// type defined outside (top level)}§ 7559 ®Colour® pants; §\C{// type defined same level}§ 7560 Face looks[10]; §\C{// type defined same level}§ 7186 7561 }; 7187 ®Colour® c = R; $\C{// type/enum defined same level}$7188 Person®.Colour® pc = Person®.®R; $\C{// type/enum defined inside}$7189 Person®.®Face pretty; $\C{// type defined inside}\CRT$7562 ®Colour® c = R; §\C{// type/enum defined same level}§ 7563 Person®.Colour® pc = Person®.®R;§\C{// type/enum defined inside}§ 7564 Person®.®Face pretty; §\C{// type defined inside}\CRT§ 7190 7565 \end{cfa} 7191 7566 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. … … 7204 7579 \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: 7205 7580 \begin{cfa} 7206 struct Y; $\C{// struct Y and struct X are at the same scope}$7581 struct Y; §\C{// struct Y and struct X are at the same scope}§ 7207 7582 struct X { 7208 7583 struct Y { /* ... */ } y; … … 7219 7594 \begin{cfa} 7220 7595 void foo() { 7221 int * b = malloc( sizeof(int) ); $\C{// implicitly convert void * to int *}$7222 char * c = b; $\C{// implicitly convert int * to void *, and then void * to char *}$7596 int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§ 7597 char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§ 7223 7598 } 7224 7599 \end{cfa} … … 7462 7837 Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in 7463 7838 \begin{cfa} 7464 int * ip = (int *)malloc( sizeof(int) ); $\C{// C}$7465 int * ip = malloc(); $\C{// \CFA type-safe version of C malloc}$7466 int * ip = alloc(); $\C{// \CFA type-safe uniform alloc}$7839 int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§ 7840 int * ip = malloc(); §\C{// \CFA type-safe version of C malloc}§ 7841 int * ip = alloc(); §\C{// \CFA type-safe uniform alloc}§ 7467 7842 \end{cfa} 7468 7843 the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©. … … 7471 7846 \begin{cfa} 7472 7847 struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment 7473 S * sp = malloc(); $\C{// honour type alignment}$7848 S * sp = malloc(); §\C{// honour type alignment}§ 7474 7849 \end{cfa} 7475 7850 the storage allocation is implicitly aligned to 128 rather than the default 16. … … 7486 7861 \CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in 7487 7862 \begin{cfa} 7488 struct S { int i; }; $\C{// cache-line alignment}$7863 struct S { int i; }; §\C{// cache-line alignment}§ 7489 7864 void ?{}( S & s, int i ) { s.i = i; } 7490 7865 // assume ?|? operator for printing an S 7491 7866 7492 S & sp = *®new®( 3 ); $\C{// call constructor after allocation}$7867 S & sp = *®new®( 3 ); §\C{// call constructor after allocation}§ 7493 7868 sout | sp.i; 7494 7869 ®delete®( &sp ); 7495 7870 7496 S * spa = ®anew®( 10, 5 ); $\C{// allocate array and initialize each array element}$7871 S * spa = ®anew®( 10, 5 ); §\C{// allocate array and initialize each array element}§ 7497 7872 for ( i; 10 ) sout | spa[i] | nonl; 7498 7873 sout | nl; … … 7533 7908 // $\CFA$ safe general allocation, fill, resize, alignment, array 7534 7909 T * alloc( void );$\indexc{alloc}$ $\C[3.5in]{// variable, T size}$ 7535 T * alloc( size_t dim ); $\C{// array[dim], T size elements}$7536 T * alloc( T ptr[], size_t dim ); $\C{// realloc array[dim], T size elements}$7537 7538 T * alloc_set( char fill );$\indexc{alloc_set}$ $\C{// variable, T size, fill bytes with value}$7539 T * alloc_set( T fill ); $\C{// variable, T size, fill with value}$7540 T * alloc_set( size_t dim, char fill ); $\C{// array[dim], T size elements, fill bytes with value}$7541 T * alloc_set( size_t dim, T fill ); $\C{// array[dim], T size elements, fill elements with value}$7542 T * alloc_set( size_t dim, const T fill[] ); $\C{// array[dim], T size elements, fill elements with array}$7543 T * alloc_set( T ptr[], size_t dim, char fill ); $\C{// realloc array[dim], T size elements, fill bytes with value}$7544 7545 T * alloc_align( size_t align ); $\C{// aligned variable, T size}$7546 T * alloc_align( size_t align, size_t dim ); $\C{// aligned array[dim], T size elements}$7547 T * alloc_align( T ptr[], size_t align ); $\C{// realloc new aligned array}$7548 T * alloc_align( T ptr[], size_t align, size_t dim ); $\C{// realloc new aligned array[dim]}$7549 7550 T * alloc_align_set( size_t align, char fill ); $\C{// aligned variable, T size, fill bytes with value}$7551 T * alloc_align_set( size_t align, T fill ); $\C{// aligned variable, T size, fill with value}$7552 T * alloc_align_set( size_t align, size_t dim, char fill ); $\C{// aligned array[dim], T size elements, fill bytes with value}$7553 T * alloc_align_set( size_t align, size_t dim, T fill ); $\C{// aligned array[dim], T size elements, fill elements with value}$7554 T * alloc_align_set( size_t align, size_t dim, const T fill[] ); $\C{// aligned array[dim], T size elements, fill elements with array}$7555 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); $\C{// realloc new aligned array[dim], fill new bytes with value}$7910 T * alloc( size_t dim ); §\C{// array[dim], T size elements}§ 7911 T * alloc( T ptr[], size_t dim ); §\C{// realloc array[dim], T size elements}§ 7912 7913 T * alloc_set( char fill );$\indexc{alloc_set}$ §\C{// variable, T size, fill bytes with value}§ 7914 T * alloc_set( T fill ); §\C{// variable, T size, fill with value}§ 7915 T * alloc_set( size_t dim, char fill ); §\C{// array[dim], T size elements, fill bytes with value}§ 7916 T * alloc_set( size_t dim, T fill ); §\C{// array[dim], T size elements, fill elements with value}§ 7917 T * alloc_set( size_t dim, const T fill[] ); §\C{// array[dim], T size elements, fill elements with array}§ 7918 T * alloc_set( T ptr[], size_t dim, char fill ); §\C{// realloc array[dim], T size elements, fill bytes with value}§ 7919 7920 T * alloc_align( size_t align ); §\C{// aligned variable, T size}§ 7921 T * alloc_align( size_t align, size_t dim ); §\C{// aligned array[dim], T size elements}§ 7922 T * alloc_align( T ptr[], size_t align ); §\C{// realloc new aligned array}§ 7923 T * alloc_align( T ptr[], size_t align, size_t dim ); §\C{// realloc new aligned array[dim]}§ 7924 7925 T * alloc_align_set( size_t align, char fill ); §\C{// aligned variable, T size, fill bytes with value}§ 7926 T * alloc_align_set( size_t align, T fill ); §\C{// aligned variable, T size, fill with value}§ 7927 T * alloc_align_set( size_t align, size_t dim, char fill ); §\C{// aligned array[dim], T size elements, fill bytes with value}§ 7928 T * alloc_align_set( size_t align, size_t dim, T fill ); §\C{// aligned array[dim], T size elements, fill elements with value}§ 7929 T * alloc_align_set( size_t align, size_t dim, const T fill[] ); §\C{// aligned array[dim], T size elements, fill elements with array}§ 7930 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); §\C{// realloc new aligned array[dim], fill new bytes with value}§ 7556 7931 7557 7932 // $\CFA$ safe initialization/copy, i.e., implicit size specification … … 7614 7989 \leavevmode 7615 7990 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7616 forall( T | { int ?<?( T, T ); } ) $\C{// location}$7991 forall( T | { int ?<?( T, T ); } ) §\C{// location}§ 7617 7992 T * bsearch( T key, const T * arr, size_t dim );$\indexc{bsearch}$ 7618 7993 7619 forall( T | { int ?<?( T, T ); } ) $\C{// position}$7994 forall( T | { int ?<?( T, T ); } ) §\C{// position}§ 7620 7995 unsigned int bsearch( T key, const T * arr, size_t dim ); 7621 7996 … … 7624 7999 7625 8000 forall( E | { int ?<?( E, E ); } ) { 7626 E * bsearch( E key, const E * vals, size_t dim );$\indexc{bsearch}$ $\C{// location}$7627 size_t bsearch( E key, const E * vals, size_t dim ); $\C{// position}$8001 E * bsearch( E key, const E * vals, size_t dim );$\indexc{bsearch}$ §\C{// location}§ 8002 size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§ 7628 8003 E * bsearchl( E key, const E * vals, size_t dim );$\indexc{bsearchl}$ 7629 8004 size_t bsearchl( E key, const E * vals, size_t dim ); … … 7672 8047 void srandom( unsigned int seed );$\indexc{srandom}$ 7673 8048 char random( void );$\indexc{random}$ 7674 char random( char u ); $\C{// [0,u)}$7675 char random( char l, char u ); $\C{// [l,u]}$8049 char random( char u ); §\C{// [0,u)}§ 8050 char random( char l, char u ); §\C{// [l,u]}§ 7676 8051 int random( void ); 7677 int random( int u ); $\C{// [0,u)}$7678 int random( int l, int u ); $\C{// [l,u]}$8052 int random( int u ); §\C{// [0,u)}§ 8053 int random( int l, int u ); §\C{// [l,u]}§ 7679 8054 unsigned int random( void ); 7680 unsigned int random( unsigned int u ); $\C{// [0,u)}$7681 unsigned int random( unsigned int l, unsigned int u ); $\C{// [l,u]}$8055 unsigned int random( unsigned int u ); §\C{// [0,u)}§ 8056 unsigned int random( unsigned int l, unsigned int u ); §\C{// [l,u]}§ 7682 8057 long int random( void ); 7683 long int random( long int u ); $\C{// [0,u)}$7684 long int random( long int l, long int u ); $\C{// [l,u]}$8058 long int random( long int u ); §\C{// [0,u)}§ 8059 long int random( long int l, long int u ); §\C{// [l,u]}§ 7685 8060 unsigned long int random( void ); 7686 unsigned long int random( unsigned long int u ); $\C{// [0,u)}$7687 unsigned long int random( unsigned long int l, unsigned long int u ); $\C{// [l,u]}$7688 float random( void ); $\C{// [0.0, 1.0)}$7689 double random( void ); $\C{// [0.0, 1.0)}$7690 float _Complex random( void ); $\C{// [0.0, 1.0)+[0.0, 1.0)i}$7691 double _Complex random( void ); $\C{// [0.0, 1.0)+[0.0, 1.0)i}$7692 long double _Complex random( void ); $\C{// [0.0, 1.0)+[0.0, 1.0)i}$8061 unsigned long int random( unsigned long int u ); §\C{// [0,u)}§ 8062 unsigned long int random( unsigned long int l, unsigned long int u ); §\C{// [l,u]}§ 8063 float random( void ); §\C{// [0.0, 1.0)}§ 8064 double random( void ); §\C{// [0.0, 1.0)}§ 8065 float _Complex random( void ); §\C{// [0.0, 1.0)+[0.0, 1.0)i}§ 8066 double _Complex random( void ); §\C{// [0.0, 1.0)+[0.0, 1.0)i}§ 8067 long double _Complex random( void ); §\C{// [0.0, 1.0)+[0.0, 1.0)i}§ 7693 8068 \end{cfa} 7694 8069 … … 7889 8264 long double atan2( long double, long double ); 7890 8265 7891 float atan( float, float ); $\C{// alternative name for atan2}$8266 float atan( float, float ); §\C{// alternative name for atan2}§ 7892 8267 double atan( double, double );$\indexc{atan}$ 7893 8268 long double atan( long double, long double ); … … 8116 8491 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8117 8492 struct Duration { 8118 int64_t tn; $\C{// nanoseconds}$8493 int64_t tn; §\C{// nanoseconds}§ 8119 8494 }; 8120 8495 … … 8261 8636 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8262 8637 struct Time { 8263 uint64_t tn; $\C{// nanoseconds since UNIX epoch}$8638 uint64_t tn; §\C{// nanoseconds since UNIX epoch}§ 8264 8639 }; 8265 8640 … … 8326 8701 \leavevmode 8327 8702 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8328 struct Clock { $\C{// virtual clock}$8329 Duration offset; $\C{// offset from computer real-time}$8703 struct Clock { §\C{// virtual clock}§ 8704 Duration offset; §\C{// offset from computer real-time}§ 8330 8705 }; 8331 8706 8332 void ?{}( Clock & clk ); $\C{// create no offset}$8333 void ?{}( Clock & clk, Duration adj ); $\C{// create with offset}$8334 void reset( Clock & clk, Duration adj ); $\C{// change offset}$8335 8336 Duration resolutionHi(); $\C{// clock resolution in nanoseconds (fine)}$8337 Duration resolution(); $\C{// clock resolution without nanoseconds (coarse)}$8338 8339 Time timeHiRes(); $\C{// real time with nanoseconds}$8340 Time time(); $\C{// real time without nanoseconds}$8341 Time time( Clock & clk ); $\C{// real time for given clock}$8342 Time ?()( Clock & clk ); $\C{//\ \ \ \ alternative syntax}$8343 timeval time( Clock & clk ); $\C{// convert to C time format}$8707 void ?{}( Clock & clk ); §\C{// create no offset}§ 8708 void ?{}( Clock & clk, Duration adj ); §\C{// create with offset}§ 8709 void reset( Clock & clk, Duration adj ); §\C{// change offset}§ 8710 8711 Duration resolutionHi(); §\C{// clock resolution in nanoseconds (fine)}§ 8712 Duration resolution(); §\C{// clock resolution without nanoseconds (coarse)}§ 8713 8714 Time timeHiRes(); §\C{// real time with nanoseconds}§ 8715 Time time(); §\C{// real time without nanoseconds}§ 8716 Time time( Clock & clk ); §\C{// real time for given clock}§ 8717 Time ?()( Clock & clk ); §\C{//\ \ \ \ alternative syntax}§ 8718 timeval time( Clock & clk ); §\C{// convert to C time format}§ 8344 8719 tm time( Clock & clk ); 8345 Duration processor(); $\C{// non-monotonic duration of kernel thread}$8346 Duration program(); $\C{// non-monotonic duration of program CPU}$8347 Duration boot(); $\C{// monotonic duration since computer boot}$8720 Duration processor(); §\C{// non-monotonic duration of kernel thread}§ 8721 Duration program(); §\C{// non-monotonic duration of program CPU}§ 8722 Duration boot(); §\C{// monotonic duration since computer boot}§ 8348 8723 \end{cfa} 8349 8724 … … 8386 8761 \begin{cfa} 8387 8762 struct PRNG { ... }; $\C[3.75in]{// opaque type}$ 8388 void ?{}( PRNG & prng ); $\C{// random seed}$8389 void ?{}( PRNG & prng, uint32_t seed ); $\C{// fixed seed}$8390 void set_seed( PRNG & prng, uint32_t seed ); $\C{// set seed}$8391 uint32_t get_seed( PRNG & prng ); $\C{// get seed}$8392 uint32_t prng( PRNG & prng ); $\C{// [0,UINT\_MAX]}$8393 uint32_t prng( PRNG & prng, uint32_t u ); $\C{// [0,u)}$8394 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ); $\C{// [l,u]}$8395 uint32_t calls( PRNG & prng ); $\C{// number of calls}\CRT$8763 void ?{}( PRNG & prng ); §\C{// random seed}§ 8764 void ?{}( PRNG & prng, uint32_t seed ); §\C{// fixed seed}§ 8765 void set_seed( PRNG & prng, uint32_t seed ); §\C{// set seed}§ 8766 uint32_t get_seed( PRNG & prng ); §\C{// get seed}§ 8767 uint32_t prng( PRNG & prng ); §\C{// [0,UINT\_MAX]}§ 8768 uint32_t prng( PRNG & prng, uint32_t u ); §\C{// [0,u)}§ 8769 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8770 uint32_t calls( PRNG & prng ); §\C{// number of calls}\CRT§ 8396 8771 \end{cfa} 8397 8772 A ©PRNG© object is used to randomize behaviour or values during execution, \eg in games, a character makes a random move or an object takes on a random value. … … 8447 8822 \begin{cfa} 8448 8823 void set_seed( uint32_t seed ); $\C[3.75in]{// set global seed}$ 8449 uint32_t get_seed(); $\C{// get global seed}$8824 uint32_t get_seed(); §\C{// get global seed}§ 8450 8825 // SLOWER 8451 uint32_t prng(); $\C{// [0,UINT\_MAX]}$8452 uint32_t prng( uint32_t u ); $\C{// [0,u)}$8453 uint32_t prng( uint32_t l, uint32_t u ); $\C{// [l,u]}$8826 uint32_t prng(); §\C{// [0,UINT\_MAX]}§ 8827 uint32_t prng( uint32_t u ); §\C{// [0,u)}§ 8828 uint32_t prng( uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8454 8829 // FASTER 8455 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th ); $\C{// [0,UINT\_MAX]}$8456 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t u ); $\C{// [0,u)}$8457 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t l, uint32_t u ); $\C{// [l,u]}\CRT$8830 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th ); §\C{// [0,UINT\_MAX]}§ 8831 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t u ); §\C{// [0,u)}§ 8832 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t l, uint32_t u ); §\C{// [l,u]}\CRT§ 8458 8833 \end{cfa} 8459 8834 The only difference between the two sets of ©prng© routines is performance. … … 8536 8911 8537 8912 \begin{cfa} 8538 void ?{}( Int * this ); $\C{// constructor/destructor}$8913 void ?{}( Int * this ); §\C{// constructor/destructor}§ 8539 8914 void ?{}( Int * this, Int init ); 8540 8915 void ?{}( Int * this, zero_t ); … … 8545 8920 void ^?{}( Int * this ); 8546 8921 8547 Int ?=?( Int * lhs, Int rhs ); $\C{// assignment}$8922 Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§ 8548 8923 Int ?=?( Int * lhs, long int rhs ); 8549 8924 Int ?=?( Int * lhs, unsigned long int rhs ); … … 8562 8937 unsigned long int narrow( Int val ); 8563 8938 8564 int ?==?( Int oper1, Int oper2 ); $\C{// comparison}$8939 int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§ 8565 8940 int ?==?( Int oper1, long int oper2 ); 8566 8941 int ?==?( long int oper2, Int oper1 ); … … 8598 8973 int ?>=?( unsigned long int oper1, Int oper2 ); 8599 8974 8600 Int +?( Int oper ); $\C{// arithmetic}$8975 Int +?( Int oper ); §\C{// arithmetic}§ 8601 8976 Int -?( Int oper ); 8602 8977 Int ~?( Int oper ); … … 8680 9055 Int ?>>=?( Int * lhs, mp_bitcnt_t shift ); 8681 9056 8682 Int abs( Int oper ); $\C{// number functions}$9057 Int abs( Int oper ); §\C{// number functions}§ 8683 9058 Int fact( unsigned long int N ); 8684 9059 Int gcd( Int oper1, Int oper2 ); … … 8692 9067 Int sqrt( Int oper ); 8693 9068 8694 forall( dtype istype | istream( istype ) ) istype * ?|?( istype * is, Int * mp ); $\C{// I/O}$9069 forall( dtype istype | istream( istype ) ) istype * ?|?( istype * is, Int * mp ); §\C{// I/O}§ 8695 9070 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp ); 8696 9071 \end{cfa} … … 8791 9166 // implementation 8792 9167 struct Rational {$\indexc{Rational}$ 8793 long int numerator, denominator; $\C{// invariant: denominator > 0}$9168 long int numerator, denominator; §\C{// invariant: denominator > 0}§ 8794 9169 }; // Rational 8795 9170 8796 Rational rational(); $\C{// constructors}$9171 Rational rational(); §\C{// constructors}§ 8797 9172 Rational rational( long int n ); 8798 9173 Rational rational( long int n, long int d ); … … 8800 9175 void ?{}( Rational * r, one_t ); 8801 9176 8802 long int numerator( Rational r ); $\C{// numerator/denominator getter/setter}$9177 long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§ 8803 9178 long int numerator( Rational r, long int n ); 8804 9179 long int denominator( Rational r ); 8805 9180 long int denominator( Rational r, long int d ); 8806 9181 8807 int ?==?( Rational l, Rational r ); $\C{// comparison}$9182 int ?==?( Rational l, Rational r ); §\C{// comparison}§ 8808 9183 int ?!=?( Rational l, Rational r ); 8809 9184 int ?<?( Rational l, Rational r ); … … 8812 9187 int ?>=?( Rational l, Rational r ); 8813 9188 8814 Rational -?( Rational r ); $\C{// arithmetic}$9189 Rational -?( Rational r ); §\C{// arithmetic}§ 8815 9190 Rational ?+?( Rational l, Rational r ); 8816 9191 Rational ?-?( Rational l, Rational r ); … … 8818 9193 Rational ?/?( Rational l, Rational r ); 8819 9194 8820 double widen( Rational r ); $\C{// conversion}$9195 double widen( Rational r ); §\C{// conversion}§ 8821 9196 Rational narrow( double f, long int md ); 8822 9197
Note:
See TracChangeset
for help on using the changeset viewer.