- Timestamp:
- Apr 25, 2024, 3:48:17 PM (22 months ago)
- Branches:
- master, stuck-waitfor-destruct
- Children:
- eb7586e
- Parents:
- cf191ac (diff), 55c97e4 (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. - Location:
- doc/user
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user/Makefile
rcf191ac r7042c60 60 60 dvips ${Build}/$< -o $@ 61 61 62 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \63 ${Macros}/ common.sty ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build}62 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${Macros}/common.tex ${Macros}/common.sty \ 63 ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build} 64 64 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 65 65 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi … … 73 73 makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx 74 74 # Run again to finish citations 75 ${LaTeX} ${basename $@}.tex75 # ${LaTeX} ${basename $@}.tex 76 76 # Run again to get index title into table of contents 77 77 # ${LaTeX} ${basename $@}.tex -
doc/user/user.tex
rcf191ac r7042c60 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Feb 12 11:50:26202414 %% Update Count : 6 19913 %% Last Modified On : Tue Apr 23 14:13:10 2024 14 %% Update Count : 6623 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 69 69 \lstset{language=CFA} % CFA default lnaguage 70 70 \lstnewenvironment{C++}[1][] % use C++ style 71 {\lstset{language=C++, moredelim=**[is][\protect\color{red}]{®}{®},#1}}71 {\lstset{language=C++,escapechar=§,moredelim=**[is][\protect\color{red}]{®}{®},#1}} 72 72 {} 73 73 … … 130 130 \vspace*{\fill} 131 131 \noindent 132 \copyright\,2016, 2018, 2021 \CFA Project \\ \\132 \copyright\,2016, 2018, 2021, 2024 \CFA Project \\ \\ 133 133 \noindent 134 134 This work is licensed under the Creative Commons Attribution 4.0 International License. … … 312 312 For example, it is possible to write a type-safe \CFA wrapper ©malloc© based on the C ©malloc©: 313 313 \begin{cfa} 314 forall( dtype T| sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }314 forall( T & | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 315 315 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 316 316 double * dp = malloc(); … … 1023 1023 while () { sout | "empty"; break; } 1024 1024 do { sout | "empty"; break; } while (); 1025 for () { sout | "empty"; break; } §\C{sout | nl | nlOff;}§1026 1027 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§1028 for ( 1 ) { sout | "A"; } §\C{sout | nl;}§1029 for ( 10 ) { sout | "A"; } §\C{sout | nl;}§1030 for ( ~= 10 ) { sout | "A"; } §\C{sout | nl;}§1031 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } §\C{sout | nl;}§1032 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } §\C{sout | nl;}§1033 for ( 0.5 ~ 5.5 ) { sout | "D"; } §\C{sout | nl;}§1034 for ( 0.5 -~ 5.5 ) { sout | "E"; } §\C{sout | nl;}§1035 for ( i; 10 ) { sout | i; } §\C{sout | nl;}§1036 for ( i; ~= 10 ) { sout | i; } §\C{sout | nl;}§1037 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§1038 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§1039 for ( i; 0.5 ~ 5.5 ) { sout | i; } §\C{sout | nl;}§1040 for ( i; 0.5 -~ 5.5 ) { sout | i; } §\C{sout | nl;}§1041 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl;}§1042 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl | nl | nl;}§1025 for () { sout | "empty"; break; } §\C[3in]{sout | nl | nlOff;}§ 1026 1027 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§ 1028 for ( 1 ) { sout | "A"; } §\C{sout | nl;}§ 1029 for ( 10 ) { sout | "A"; } §\C{sout | nl;}§ 1030 for ( ~= 10 ) { sout | "A"; } §\C{sout | nl;}§ 1031 for ( 1 ~= 10 ~ 2 ) { sout | "B"; } §\C{sout | nl;}§ 1032 for ( 1 -~= 10 ~ 2 ) { sout | "C"; } §\C{sout | nl;}§ 1033 for ( 0.5 ~ 5.5 ) { sout | "D"; } §\C{sout | nl;}§ 1034 for ( 0.5 -~ 5.5 ) { sout | "E"; } §\C{sout | nl;}§ 1035 for ( i; 10 ) { sout | i; } §\C{sout | nl;}§ 1036 for ( i; ~= 10 ) { sout | i; } §\C{sout | nl;}§ 1037 for ( i; 1 ~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§ 1038 for ( i; 1 -~= 10 ~ 2 ) { sout | i; } §\C{sout | nl;}§ 1039 for ( i; 0.5 ~ 5.5 ) { sout | i; } §\C{sout | nl;}§ 1040 for ( i; 0.5 -~ 5.5 ) { sout | i; } §\C{sout | nl;}§ 1041 for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl;}§ 1042 for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } §\C{sout | nl | nl | nl;}§ 1043 1043 1044 1044 enum { N = 10 }; 1045 for ( N ) { sout | "N"; } §\C{sout | nl;}§1046 for ( i; N ) { sout | i; } §\C{sout | nl;}§1047 for ( i; -~ N ) { sout | i; } §\C{sout | nl | nl | nl;}§1045 for ( N ) { sout | "N"; } §\C{sout | nl;}§ 1046 for ( i; N ) { sout | i; } §\C{sout | nl;}§ 1047 for ( i; -~ N ) { sout | i; } §\C{sout | nl | nl | nl;}§ 1048 1048 1049 1049 const int low = 3, high = 10, inc = 2; 1050 for ( i; low ~ high ~ inc + 1 ) { sout | i; } §\C{sout | nl;}§1051 for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§1052 for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§1053 for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§1050 for ( i; low ~ high ~ inc + 1 ) { sout | i; } §\C{sout | nl;}§ 1051 for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§ 1052 for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§ 1053 for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§ 1054 1054 for ( i; 2.1 ~ @ ~ @ ) { if ( i > 10.5 ) break; sout | i; i += 1.7; } §\C{sout | nl;}§ 1055 1055 for ( i; @ -~ 10 ~ 2 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§ 1056 1056 for ( i; 12.1 ~ @ ~ @ ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; } §\C{sout | nl;}§ 1057 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§1058 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§1059 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1060 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1061 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§1062 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§1063 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1064 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§1057 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§ 1058 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§ 1059 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1060 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1061 for ( i; 5 : j; -5 ~ @ ) { sout | i | j; } §\C{sout | nl;}§ 1062 for ( i; 5 : j; @ -~ -5 ) { sout | i | j; } §\C{sout | nl;}§ 1063 for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1064 for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; } §\C{sout | nl;}§ 1065 1065 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1066 1066 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1067 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;} §1067 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}\CRT§ 1068 1068 \end{cfa} 1069 1069 & … … 2960 2960 The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter ©x© of type array of 5 integers. 2961 2961 Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string. 2962 2962 2963 As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity: 2963 2964 \begin{cfa} … … 2965 2966 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§ 2966 2967 \end{cfa} 2967 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.2968 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©. 2968 2969 The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name. 2969 2970 The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts. … … 3055 3056 static [ int ] g ( int ); 3056 3057 \end{cfa} 3058 3059 3060 \subsection{Postfix Function} 3061 \label{s:PostfixFunction} 3062 \index{postfix function} 3063 3064 \CFA provides an alternative call syntax where the argument appears before the function name. 3065 The syntax uses the backquote ©`© to separate the parameters/arguments and function name: ©?`© denotes a postfix-function name, \eg ©int ?`h( int s )© and ©`© denotes a postfix-function call, \eg ©0`h© meaning ©h( 0 )©. 3066 \begin{cquote} 3067 \begin{tabular}{@{}l|l|l|l@{}} 3068 postfix function & constant argument call & variable argument call & postfix function pointer \\ 3069 \hline 3070 \begin{cfa} 3071 int ?`h( int s ); 3072 int ?`h( double s ); 3073 int ?`m( char c ); 3074 int ?`m( const char * s ); 3075 int ?`t( int a, int b, int c ); 3076 \end{cfa} 3077 & 3078 \begin{cfa} 3079 0`h; 3080 3.5`h; 3081 '1'`m; 3082 "123" "456"`m; 3083 [1, 2, 3]`t; 3084 \end{cfa} 3085 & 3086 \begin{cfa} 3087 int i = 7; 3088 i`h; 3089 (i + 3)`h; 3090 (i + 3.5)`h; 3091 \end{cfa} 3092 & 3093 \begin{cfa} 3094 int (* ?`p)( int i ); 3095 ?`p = ?`h; 3096 3`p; 3097 i`p; 3098 (i + 3)`p; 3099 \end{cfa} 3100 \end{tabular} 3101 \end{cquote} 3102 Note, to pass \emph{multiple} arguments to a postfix function requires a \Index{tuple}, \eg ©[1, 2, 3]`t©, which forms a single argument that is flattened into the multiple arguments \see{\VRef{s:Tuple}}. 3103 Similarly, if the argument is an expression, it must be parenthesized, \eg ©(i + 3)`h©, or only the last operand of the expression is the argument, \eg ©i + (3`h)©. 3104 3105 \VRef[Figure]{f:UnitsComparison} shows a common usage for postfix functions: converting basic literals into user literals. 3106 \see*{\VRef{s:DynamicStorageManagement} for other uses for postfix functions.} 3107 The \CFA example (left) stores a mass in units of stones (1 stone = 14 lb or 6.35 kg) and provides an addition operator (imagine a full set of arithmetic operators). 3108 The three postfixing function names ©st©, ©lb©, and ©kg©, represent units stones, pounds, and kilograms, respectively. 3109 Each name has two forms that bidirectional convert: a value of a specified unit to stones, \eg ©w = 14`lb© $\Rightarrow$ ©w == 1© stone or a ©Weight© from stones back to specific units, \eg ©w`lb© (1 stone) to ©14©. 3110 All arithmetic operations manipulate stones and the postfix operations convert to the different units. 3111 A similar group of postfix functions provide user constants for converting time units into nanoseconds, which is the basic time unit, \eg ©ns©, ©us©, ©ms©, ©s©, ©m©, ©h©, ©d©, and ©w©, for nanosecond, microsecond, millisecond, second, minute, hour, day, and week, respectively. 3112 (Note, month is not a fixed period of time nor is year because of leap years.) 3113 3114 \begin{figure} 3115 \centering 3116 \begin{tabular}{@{}l|l@{}} 3117 \multicolumn{1}{@{}c|}{\textbf{\CFA Postfix Routine}} & \multicolumn{1}{c@{}}{\textbf{\CC User Literals}} \\ 3118 \hline 3119 \begin{cfa} 3120 struct Weight { 3121 double stones; 3122 }; 3123 3124 3125 Weight ?+?( Weight l, Weight r ) { 3126 return l.stones + r.stones; 3127 } 3128 Weight ®?`st®( double w ) { return w; } 3129 double ®?`st®( Weight w ) { return w.stones; } 3130 Weight ®?`lb®( double w ) { return w / 14.0; } 3131 double ®?`lb®( Weight w ) { return w.stones * 14.0; } 3132 Weight ®?`kg®( double w ) { return w / 6.35; } 3133 double ®?`kg®( Weight w ) { return w.stones * 6.35; } 3134 int main() { 3135 Weight w, heavy = { 20 }; // stones 3136 w = 155®`lb®; 3137 w = 0b_1111®`st®; 3138 w = 0_233®`lb®; 3139 w = 0x_9b®`kg®; 3140 w = 5.5®`st® + 8®`kg® + 25.01®`lb® + heavy; 3141 } 3142 \end{cfa} 3143 & 3144 \begin{C++} 3145 struct Weight { 3146 double stones; 3147 Weight() {} 3148 Weight( double w ) { stones = w; } 3149 }; 3150 Weight operator+( Weight l, Weight r ) { 3151 return l.stones + r.stones; 3152 } 3153 Weight operator®""_st®( long double w ) { return w; } 3154 Weight operator®""_lb®( long double w ) { return w / 14.0; } 3155 Weight operator®""_kg®( long double w ) { return w / 6.35; } 3156 Weight operator®""_st®( unsigned long long int w ) { return w; } 3157 Weight operator®""_lb®( unsigned long long int w ) { return w / 14.0; } 3158 Weight operator®""_kg®( unsigned long long int w ) { return w / 6.35; } 3159 int main() { 3160 Weight w, heavy = { 20 }; // stones 3161 w = 155®_lb®; 3162 w = 0b1111®_st®; 3163 w = 0'233®_lb®; // quote separator 3164 w = 0x9b®_kg®; 3165 w = 5.5®_st® + 8®_kg® + 25.01®_lb® + heavy; 3166 } 3167 \end{C++} 3168 \end{tabular} 3169 3170 \begin{comment} 3171 Time : comparison of time units. \\ 3172 \begin{tabular}{@{}ll@{}} 3173 \CFA & \CC \\ 3174 \begin{cfa} 3175 #include <fstream.hfa> 3176 #include <time.hfa> 3177 3178 3179 Duration s = 1`h + 2 * 10`m + 70`s / 10; 3180 sout | "1 hour + 2*10 min + 70/10 sec = " | s | "seconds"; 3181 sout | "Dividing that by 2 minutes gives" | s / 2`m; 3182 sout | "Dividing that by 2 gives" | s / 2 | "seconds\n"; 3183 sout | s | "seconds is" 3184 | s`h | "hours," 3185 | (s % 1`h)`m | "minutes," 3186 | (s % 1`m)`s | "seconds"; 3187 \end{cfa} 3188 & 3189 \begin{C++} 3190 #include <iostream> 3191 #include <chrono> 3192 using namespace std; 3193 using namespace std::chrono; 3194 seconds s = hours(1) + 2 * minutes(10) + seconds(70) / 10; 3195 cout << "1 hour + 2*10 min + 70/10 sec = " << s.count() << " seconds\n"; 3196 cout << "Dividing that by 2 minutes gives " << s / minutes(2) << '\n'; 3197 cout << "Dividing that by 2 gives " << (s / 2).count() << " seconds\n"; 3198 cout << s.count() << " seconds is " 3199 << duration_cast<hours>( s ).count() << " hours, " 3200 << duration_cast<minutes>( s % hours(1) ).count() << " minutes, " 3201 << duration_cast<seconds>( s % minutes(1) ).count() << " seconds\n"; 3202 \end{C++} 3203 \end{tabular} 3204 \end{comment} 3205 3206 \caption{Units: Stone, Pound, Kilogram Comparison} 3207 \label{f:UnitsComparison} 3208 \end{figure} 3209 3210 The \CC example (right) provides a \emph{restricted} capability via user literals. 3211 The \lstinline[language=C++]{operator ""} only takes a constant argument (\ie no variable argument), and the constant type must be the highest-level constant-type, \eg ©long double© for all floating-point constants. 3212 As well, there is no constant conversion, \ie ©int© to ©double© constants, so integral constants are handled by a separate set of routines, with maximal integral type ©unsigned long long int©. 3213 Finally, there is no mechanism to use this syntax for a bidirectional conversion because \lstinline[language=C++]{operator ""} does not accept variable arguments. 3057 3214 3058 3215 … … 3389 3546 3390 3547 \section{Tuple} 3548 \label{s:Tuple} 3391 3549 3392 3550 In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call. … … 3809 3967 \subsection{Polymorphism} 3810 3968 3811 Due to the implicit flattening and structuring conversions involved in argument passing, ©otype© and ©dtype©parameters are restricted to matching only with non-tuple types.3969 Due to the implicit flattening and structuring conversions involved in argument passing, object and opaque parameters are restricted to matching only with non-tuple types. 3812 3970 The integration of polymorphism, type assertions, and monomorphic specialization of tuple-assertions are a primary contribution of this thesis to the design of tuples. 3813 3971 \begin{cfa} 3814 forall(T, dtype U)3972 forall(T, U &) 3815 3973 void f(T x, U * y); 3816 3974 … … 4047 4205 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§; 4048 4206 \end{cfa} 4049 \index{lvalue} 4050 The left-hand side is a tuple of \LstBasicStyle{\emph{lvalues}}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement. 4207 The left-hand side is a tuple of \LstBasicStyle{\emph{\Index{lvalue}}}s, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement. 4051 4208 \LstBasicStyle{\emph{expr}} is any standard arithmetic expression. 4052 4209 Clearly, the types of the entities being assigned must be type compatible with the value of the expression. … … 4086 4243 Multiple assignment has the following form: 4087 4244 \begin{cfa} 4088 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ]; 4089 \end{cfa} 4090 \index{lvalue} 4091 The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s. 4092 Each \emph{expr} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment. 4245 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ];§ 4246 \end{cfa} 4247 The left-hand side is a tuple of \LstBasicStyle{\emph{\Index{lvalue}}}s, and the right-hand side is a tuple of \LstBasicStyle{\emph{expr}}s. 4248 Each \LstBasicStyle{\emph{expr}} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \LstBasicStyle{\emph{lvalues}} on the left-hand side of the statement using parallel semantics for each assignment. 4093 4249 An example of multiple assignment is: 4094 4250 \begin{cfa} … … 4925 5081 sout | '1' | '2' | '3'; 4926 5082 sout | 1 | "" | 2 | "" | 3; 4927 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x Â¥"4928 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;5083 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" 5084 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10; 4929 5085 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 4930 | 7 | " ¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";5086 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x"; 4931 5087 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx"; 4932 5088 sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4; … … 7775 7931 \item[Rationale:] increase type safety 7776 7932 \item[Effect on original feature:] deletion of semantically well-defined feature. 7777 \item[Difficulty of converting:] requires adding a cast \see{\VRef{s: StorageManagement} for better alternatives}:7933 \item[Difficulty of converting:] requires adding a cast \see{\VRef{s:DynamicStorageManagement} for better alternatives}: 7778 7934 \begin{cfa} 7779 7935 int * b = (int *)malloc( sizeof(int) ); … … 7987 8143 \section{Standard Library} 7988 8144 \label{s:StandardLibrary} 7989 7990 The \CFA standard-library wraps explicitly-polymorphic C routines into implicitly-polymorphic versions. 7991 7992 7993 \subsection{Storage Management} 7994 \label{s:StorageManagement} 7995 7996 The storage-management routines extend their C equivalents by overloading, alternate names, providing shallow type-safety, and removing the need to specify the allocation size for non-array types. 7997 7998 C storage management provides the following capabilities: 7999 \begin{description} 8000 \item[filled] 8001 after allocation with a specified character or value. 8145 \index{standard library} 8146 8147 The \CFA standard-library extends existing C library routines by adding new function, wrapping existing explicitly-polymorphic C routines into implicitly-polymorphic versions, and adding new \CFA extensions. 8148 8149 8150 \subsection{Dynamic Storage-Management} 8151 \label{s:DynamicStorageManagement} 8152 \index{dynamic storage-management}\index{storage management} 8153 8154 Dynamic storage-management in C is based on explicit allocation and deallocation (©malloc©/©free©). 8155 Programmer's must manage all allocated storage via its address (pointer) and subsequently deallocate the storage via this address. 8156 Storage that is not deallocated becomes inaccessible, called a \newterm{memory leak}, which can only be detected at program termination. 8157 Storage freed twice is an error, called a \newterm{duplicate free}, which can sometimes be detected. 8158 Storage used after it is deallocated is an error, called using a \newterm{dangling pointer}, which can sometimes be detected. 8159 8160 8161 \subsubsection{C Interface} 8162 8163 C dynamic storage-management provides the following properties. 8164 \begin{description}[leftmargin=*] 8165 \item[fill] 8166 storage after an allocation with a specified character or value. 8167 \item[align] 8168 an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes. 8169 \item[scale] 8170 an allocation size to the specified number of array elements. 8171 An array may be filled, resized, or aligned. 8002 8172 \item[resize] 8003 8173 an existing allocation to decreased or increased its size. 8004 In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation is copied into the new allocation. 8005 For an increase in storage size, new storage after the copied data may be filled. 8006 \item[align] 8007 an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes. 8008 \item[array] 8009 the allocation size is scaled to the specified number of array elements. 8010 An array may be filled, resized, or aligned. 8174 In either direction, new storage may or may not be allocated, but if there is a new allocation, as much data from the existing allocation is copied into the new allocation. 8175 When new storage is allocated, it may be aligned and storage after copied data may be filled. 8011 8176 \end{description} 8012 \VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities. 8177 \VRef[Table]{t:AllocationVersusProperties} shows different combinations of storage-management properties provided by the C and \CFA allocation routines. 8178 8013 8179 \begin{table} 8180 \caption{Allocation Routines versus Storage-Management Properties} 8181 \label{t:AllocationVersusProperties} 8014 8182 \centering 8015 8183 \begin{minipage}{0.75\textwidth} 8016 8184 \begin{tabular}{@{}r|l|l|l|l|l@{}} 8017 \multicolumn{1}{c}{}& & \multicolumn{1}{c|}{fill} & resize & alignment & array\\8185 & \multicolumn{1}{c|}{routine} & \multicolumn{1}{c|}{\textbf{fill}} & \textbf{alignment} & \textbf{scale} & \textbf{resize} \\ 8018 8186 \hline 8019 8187 C & ©malloc© & no & no & no & no \\ 8020 & ©calloc© & yes (0 only) & no & no & yes \\ 8021 & ©realloc© & copy & yes & no & no \\ 8022 & ©memalign© & no & no & yes & no \\ 8023 & ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment, which is universally ignored.} 8024 & no & no & yes & no \\ 8025 & ©posix_memalign© & no & no & yes & no \\ 8026 & ©valloc© & no & no & yes (page size)& no \\ 8188 & ©calloc© & yes (0 only) & no & yes & no \\ 8189 & ©realloc© & copy & no & no & yes \\ 8190 & ©reallocarray© & copy & no & yes & yes \\ 8191 & ©memalign© & no & yes & no & no \\ 8192 & ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment.} 8193 & no & yes & no & no \\ 8194 & ©posix_memalign© & no & yes & no & no \\ 8195 & ©valloc© & no & yes (page size)& no & no \\ 8027 8196 & ©pvalloc©\footnote{Same as ©valloc© but rounds size to multiple of page size.} 8028 & no & no & yes (page size)& no \\ 8029 \hline 8030 \CFA & ©cmemalign© & yes (0 only) & no & yes & yes \\ 8031 & ©realloc© & copy & yes & yes & no \\ 8032 & ©alloc© & no & yes & no & yes \\ 8033 & ©alloc_set© & yes & yes & no & yes \\ 8034 & ©alloc_align© & no & yes & yes & yes \\ 8035 & ©alloc_align_set© & yes & yes & yes & yes \\ 8197 & no & yes (page size)& no & no \\ 8198 \hline 8199 \CFA & ©cmemalign© & yes (0 only) & yes & yes & no \\ 8200 & ©resize© & no copy & yes & no & yes \\ 8201 & ©realloc© & copy & yes & no & yes \\ 8202 & ©alloc©\footnote{Multiple overloads with different parameters.} 8203 & yes & yes & yes & yes 8036 8204 \end{tabular} 8037 8205 \end{minipage} 8038 \caption{Allocation Routines versus Storage-Management Capabilities} 8039 \label{t:AllocationVersusCapabilities} 8206 \vspace*{-10pt} 8040 8207 \end{table} 8041 8208 8042 \CFA memory management extends the type safety of all allocations by using the type of the left-hand-side type to determine the allocation size and return a matching type for the new storage. 8043 Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in 8044 \begin{cfa} 8045 int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§ 8046 int * ip = malloc(); §\C{// \CFA type-safe version of C malloc}§ 8047 int * ip = alloc(); §\C{// \CFA type-safe uniform alloc}§ 8048 \end{cfa} 8049 the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©. 8050 8051 \CFA memory management extends allocation safety by implicitly honouring all alignment requirements, \eg in 8052 \begin{cfa} 8053 struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment 8054 S * sp = malloc(); §\C{// honour type alignment}§ 8055 \end{cfa} 8056 the storage allocation is implicitly aligned to 128 rather than the default 16. 8057 The alignment check is performed at compile time so there is no runtime cost. 8058 8059 \CFA memory management extends the resize capability with the notion of \newterm{sticky properties}. 8060 Hence, initial allocation capabilities are remembered and maintained when resize requires copying. 8061 For example, an initial alignment and fill capability are preserved during a resize copy so the copy has the same alignment and extended storage is filled. 8062 Without sticky properties it is dangerous to use ©realloc©, resulting in an idiom of manually performing the reallocation to maintain correctness. 8063 \begin{cfa} 8064 8065 \end{cfa} 8066 8067 \CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in 8068 \begin{cfa} 8069 struct S { int i; }; §\C{// cache-line alignment}§ 8070 void ?{}( S & s, int i ) { s.i = i; } 8071 // assume ?|? operator for printing an S 8072 8073 S & sp = *®new®( 3 ); §\C{// call constructor after allocation}§ 8074 sout | sp.i; 8075 ®delete®( &sp ); 8076 8077 S * spa = ®anew®( 10, 5 ); §\C{// allocate array and initialize each array element}§ 8078 for ( i; 10 ) sout | spa[i] | nonl; 8079 sout | nl; 8080 ®adelete®( 10, spa ); 8209 8210 \subsubsection{\CFA Interface} 8211 8212 \CFA dynamic memory management: 8213 \begin{enumerate}[leftmargin=\parindent] 8214 \item 8215 extends type safety of all allocation routines by using the left-hand assignment type to determine the allocation size and alignment, and return a matching type for the new storage, which removes many common allocation errors. 8216 \begin{cfa} 8217 int * ip = (int *)malloc( sizeof(int) ); §\C[2.3in]{// C}§ 8218 int * ip = malloc(); §\C{// \CFA type-safe call of C malloc}§ 8219 int * ip = calloc(); §\C{// \CFA type-safe call of C calloc}§ 8220 struct __attribute__(( aligned(128) )) spinlock { ... }; // cache alignment 8221 spinlock * slp = malloc(); §\C{// correct size, alignment, and return type}\CRT§ 8222 \end{cfa} 8223 Here, the alignment of the ©ip© storage is 16 (default) and 128 for ©slp©. 8224 8225 \item 8226 introduces the notion of \newterm{sticky properties} used in resizing. 8227 All initial allocation properties are remembered and maintained for use should resize require new storage. 8228 For example, the initial alignment and fill properties in the initial allocation 8229 \begin{cfa} 8230 struct __attribute__(( aligned(4096) )) S { ... }; 8231 S * sp = calloc( 10 ); §\C{// align 4K and zero fill}§ 8232 sp = reallocarray( sp, 100 ); §\C{// preserve 4K alignment and zero fill new storage}§ 8233 \end{cfa} 8234 are preserved in the resize so the new storage has the same alignment and extra storage after the data copy is zero filled. 8235 Without sticky properties it is dangerous to resize, resulting in the C idiom of manually performing the reallocation to maintain correctness, which is error prone. 8236 8237 \item 8238 provides resizing without data copying, which is useful to repurpose an existing block of storage, rather than freeing the old storage and performing a new allocation. 8239 A resize can take advantage of unused storage after the data to preventing a free/reallocation step altogether. 8240 8241 \item 8242 provides ©free©/©delete© functions that delete a variable number of allocations. 8243 \begin{cfa} 8244 int * ip = malloc(), * jp = malloc(), * kp = malloc(); 8245 double * xp = malloc(), * yp = malloc(), * zp = malloc(); 8246 free( ®ip, jp, kp, xp, yp, zp® ); §\C{// multiple deallocations}§ 8247 \end{cfa} 8248 8249 \item 8250 supports constructors for initialization of allocated storage and destructors for deallocation (like \CC). 8251 \begin{cfa} 8252 struct S { int v; }; §\C{// default constructors}§ 8253 void ^?{}( S & ) { ... } §\C{// destructor}§ 8254 S & sp = *®new®( 3 ); §\C{// allocate and call constructor}§ 8255 sout | sp.v; 8256 ®delete®( &sp ); §\C{// call destructor}§ 8257 S * spa1 = ®anew®( 10, 5 ), * spa2 = ®anew®( 10, 8 ); §\C{// allocate array and call constructor for each array element}§ 8258 for ( i; 10 ) sout | spa1[i].v | spa2[i].v | nonl; sout | nl; 8259 ®adelete®( spa1, spa2 ); §\C{// call destructors on all array objects}§ 8260 8261 3 8262 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 8081 8263 \end{cfa} 8082 8264 Allocation routines ©new©/©anew© allocate a variable/array and initialize storage using the allocated type's constructor. 8083 8265 Note, the matching deallocation routines ©delete©/©adelete©. 8084 8085 \leavevmode 8266 \CC only supports the default constructor for intializing array elements. 8267 \begin{C++} 8268 S * sp = new S[10]®{5}®; §\C{// disallowed}§ 8269 \end{C++} 8270 \end{enumerate} 8271 8272 In addition, \CFA provides a new allocator interface to further increase orthogonality and usability of dynamic-memory allocation. 8273 This interface helps programmers in three ways. 8274 \begin{enumerate} 8275 \item 8276 naming: \CFA regular and ©ttype© polymorphism (similar to \CC variadic templates) is used to encapsulate a wide range of allocation functionality into a single routine name, so programmers do not have to remember multiple routine names for different kinds of dynamic allocations. 8277 \item 8278 named arguments: individual allocation properties are specified using postfix function call \see{\VRef{s:PostfixFunction}}, so programmers do not have to remember parameter positions in allocation calls. 8279 \item 8280 safe usage: like the \CFA's C-interface, programmers do not have to specify object size or cast allocation results. 8281 \end{enumerate} 8282 8283 The polymorphic functions 8284 \begin{cfa} 8285 T * alloc( ... ); 8286 T * alloc( size_t dim, ... ); 8287 \end{cfa} 8288 are overloaded with a variable number of allocation properties. 8289 These allocation properties can be passed as named arguments when calling the \Indexc{alloc} routine. 8290 A call without parameters returns an uninitialized dynamically allocated object of type ©T© (\Indexc{malloc}). 8291 A call with only the dimension (dim) parameter returns an uninitialized dynamically allocated array of objects with type ©T© (\Indexc{aalloc}). 8292 The variable number of arguments consist of allocation properties to specialize the allocation. 8293 The properties ©resize© and ©realloc© are associated with an existing allocation variable indicating how its storage is modified. 8294 8295 The following allocation property functions may be combined and appear in any order as arguments to ©alloc©, 8296 \begin{itemize} 8297 \item 8298 ©T_align ?`align( size_t alignment )© to align an allocation. 8299 The alignment parameter must be $\ge$ the default alignment (©libAlign()© in \CFA) and a power of two, \eg the following return a dynamic object and object array aligned on a 256 and 4096-byte boundary. 8300 \begin{cfa} 8301 int * i0 = alloc( ®256`align® ); sout | i0 | nl; 8302 int * i1 = alloc( 3, ®4096`align® ); for (i; 3 ) sout | &i1[i] | nonl; sout | nl; 8303 free( i0, i1 ); 8304 8305 0x5555565699®00® // 256 alignment 8306 0x55555656c®000® 0x5656c004 0x5656c008 // 4K array alignment 8307 \end{cfa} 8308 8309 \item 8310 ©T_fill(T) ?`fill( /* various types */ )© to initialize storage. 8311 There are three ways to fill storage: 8312 \begin{enumerate} 8313 \item 8314 A ©char© fills every byte of each object. 8315 \item 8316 An object of the returned type fills each object. 8317 \item 8318 An object array pointer fills some or all of the corresponding object array. 8319 \end{enumerate} 8320 For example: 8321 \begin{cfa}[numbers=left] 8322 int * i0 = alloc( ®0n`fill® ); sout | *i0 | nl; // 0n disambiguates 0p 8323 int * i1 = alloc( ®5`fill® ); sout | *i1 | nl; 8324 int * i2 = alloc( ®'\xfe'`fill® ); sout | hex( *i2 ) | nl; 8325 int * i3 = alloc( 5, ®5`fill® ); for ( i; 5 ) sout | i3[i] | nonl; sout | nl; 8326 int * i4 = alloc( 5, ®0xdeadbeefN`fill® ); for ( i; 5 ) sout | hex( i4[i] ) | nonl; sout | nl; 8327 int * i5 = alloc( 5, ®i3`fill® ); for ( i; 5 ) sout | i5[i] | nonl; sout | nl; // completely fill from i3 8328 int * i6 = alloc( 5, ®[i3, 3]`fill® ); for ( i; 5 ) sout | i6[i] | nonl; sout | nl; // partial fill from i3 8329 free( i0, i1, i2, i3, i4, i5, i6 ); 8330 \end{cfa} 8331 \begin{lstlisting}[numbers=left] 8332 0 8333 5 8334 0xfefefefe 8335 5 5 5 5 5 8336 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 8337 5 5 5 5 5 8338 5 5 5 -555819298 -555819298 // two undefined values 8339 \end{lstlisting} 8340 Examples 1 to 3 fill an object with a value or characters. 8341 Examples 4 to 7 fill an array of objects with values, another array, or part of an array. 8342 8343 \item 8344 ©S_resize(T) ?`resize( void * oaddr )© used to resize, realign, and fill, where the old object data is not copied to the new object. 8345 The old object type may be different from the new object type, since the values are not used. 8346 For example: 8347 \begin{cfa}[numbers=left] 8348 int * ip = alloc( ®5`fill® ); sout | ip | *ip; 8349 ip = alloc( ®ip`resize®, ®256`align®, ®7`fill® ); sout | ip | *ip; 8350 double * dp = alloc( ®ip`resize®, ®4096`align®, ®13.5`fill® ); sout | dp | *dp; 8351 free( dp ); // DO NOT FREE ip AS ITS STORAGE IS MOVED TO dp 8352 \end{cfa} 8353 \begin{lstlisting}[numbers=left] 8354 0x555555580a80 5 8355 0x555555581100 7 8356 0x555555587000 13.5 8357 \end{lstlisting} 8358 Examples 2 to 3 change the alignment, fill, and size for the initial storage of ©i©. 8359 8360 \begin{cfa}[numbers=left] 8361 int * ia = alloc( 5, ®5`fill® ); sout | ia | nonl; for ( i; 5 ) sout | ia[i] | nonl; sout | nl; 8362 ia = alloc( 10, ®ia`resize®, ®7`fill® ); sout | ia | nonl; for ( i; 10 ) sout | ia[i] | nonl; sout | nl; 8363 ia = alloc( 5, ®ia`resize®, ®512`align®, ®13`fill® ); sout | ia | nonl; for ( i; 5 ) sout | ia[i] | nonl; sout | nl;; 8364 ia = alloc( 3, ®ia`resize®, ®4096`align®, ®2`fill® ); for ( i; 3 ) sout | &ia[i] | ia[i] | nonl; sout | nl; 8365 free( ia ); 8366 \end{cfa} 8367 \begin{lstlisting}[numbers=left] 8368 0x55555656d540 5 5 5 5 5 8369 0x55555656d480 7 7 7 7 7 7 7 7 7 7 8370 0x55555656fe00 13 13 13 13 13 8371 0x555556570000 2 0x555556570004 2 0x555556570008 2 8372 \end{lstlisting} 8373 Examples 2 to 4 change the array size, alignment, and fill initializes all storage because no data is copied. 8374 8375 \item 8376 ©S_realloc(T) ?`realloc( T * a ))© 8377 used to resize, realign, and fill, where the old object data is copied to the new object. 8378 The old object type must be the same as the new object type, since the value is used. 8379 Note, for ©fill©, only the extra space after copying the data from the old object is filled with the given parameter. 8380 For example: 8381 \begin{cfa}[numbers=left] 8382 int * ip = alloc( ®5`fill® ); sout | ip | *ip; 8383 ip = alloc( ®ip`realloc®, ®256`align® ); sout | ip | *ip; 8384 ip = alloc( ®ip`realloc®, ®4096`align®, ®13`fill® ); sout | ip | *ip; 8385 free( ip ); 8386 \end{cfa} 8387 \begin{lstlisting}[numbers=left] 8388 0x55555556d5c0 5 8389 0x555555570000 5 8390 0x555555571000 5 8391 \end{lstlisting} 8392 Examples 2 to 3 change the alignment for the initial storage of ©i©. 8393 The ©13`fill© in example 3 does nothing because no new storage is added. 8394 8395 \begin{cfa}[numbers=left] 8396 int * ia = alloc( 5, ®5`fill® ); sout | ia | nonl; for ( i; 5 ) sout | ia[i] | nonl; sout | nl; 8397 ia = alloc( 10, ®ia`realloc®, ®7`fill® ); sout | ia | nonl; for ( i; 10 ) sout | ia[i] | nonl; sout | nl; 8398 ia = alloc( 5, ®ia`realloc®, ®512`align®, ®13`fill® ); sout | ia | nonl; for ( i; 5 ) sout | ia[i] | nonl; sout | nl;; 8399 ia = alloc( 3, ®ia`realloc®, ®4096`align®, ®2`fill® ); for ( i; 3 ) sout | &ia[i] | ia[i] | nonl; sout | nl; 8400 free( ia ); 8401 \end{cfa} 8402 \begin{lstlisting}[numbers=left] 8403 0x55555656d540 5 5 5 5 5 8404 0x55555656d480 7 7 7 7 7 7 7 7 7 7 8405 0x555556570e00 5 5 5 5 5 8406 0x5555556571000 5 0x555556571004 5 0x555556571008 5 8407 \end{lstlisting} 8408 Examples 2 to 4 change the array size, alignment, and fill does no initialization after the copied data, as no new storage is added. 8409 \end{itemize} 8410 8411 \medskip 8086 8412 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8087 8413 extern "C" { 8088 // C unsafe allocation 8089 void * malloc( size_t size );§\indexc{malloc}§ 8090 void * calloc( size_t dim, size_t size );§\indexc{calloc}§ 8091 void * realloc( void * ptr, size_t size );§\indexc{realloc}§ 8092 void * memalign( size_t align, size_t size );§\indexc{memalign}§ 8093 void * aligned_alloc( size_t align, size_t size );§\indexc{aligned_alloc}§ 8094 int posix_memalign( void ** ptr, size_t align, size_t size );§\indexc{posix_memalign}§ 8095 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );§\indexc{cmemalign}§ // CFA 8096 8097 // C unsafe initialization/copy 8098 void * memset( void * dest, int c, size_t size );§\indexc{memset}§ 8099 void * memcpy( void * dest, const void * src, size_t size );§\indexc{memcpy}§ 8100 } 8101 8102 void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap 8103 8104 forall( dtype T | sized(T) ) { 8105 // §\CFA§ safe equivalents, i.e., implicit size specification 8106 T * malloc( void ); 8107 T * calloc( size_t dim ); 8108 T * realloc( T * ptr, size_t size ); 8109 T * memalign( size_t align ); 8110 T * cmemalign( size_t align, size_t dim ); 8111 T * aligned_alloc( size_t align ); 8112 int posix_memalign( T ** ptr, size_t align ); 8414 // New C allocation operations. 8415 void * aalloc( size_t dim, size_t elemSize );§\indexc{aalloc}§ 8416 void * resize( void * oaddr, size_t size );§\indexc{resize}§ 8417 void * amemalign( size_t align, size_t dim, size_t elemSize );§\indexc{amemalign}§ 8418 void * cmemalign( size_t align, size_t dim, size_t elemSize );§\indexc{cmemalign}§ 8419 size_t malloc_alignment( void * addr );§\indexc{malloc_alignment}§ 8420 bool malloc_zero_fill( void * addr );§\indexc{malloc_zero_fill}§ 8421 size_t malloc_size( void * addr );§\indexc{malloc_size}§ 8422 int malloc_stats_fd( int fd );§\indexc{malloc_stats_fd}§ 8423 size_t malloc_expansion();§\indexc{malloc_expansion}§ §\C{// heap expansion size (bytes)}§ 8424 size_t malloc_mmap_start();§\indexc{malloc_mmap_start}§ §\C{// crossover allocation size from sbrk to mmap}§ 8425 size_t malloc_unfreed();§\indexc{malloc_unfreed()}§ §\C{// heap unfreed size (bytes)}§ 8426 void malloc_stats_clear();§\indexc{malloc_stats_clear}§ §\C{// clear heap statistics}§ 8427 } 8428 8429 // New allocation operations. 8430 void * resize( void * oaddr, size_t alignment, size_t size ); 8431 void * realloc( void * oaddr, size_t alignment, size_t size ); 8432 void * reallocarray( void * oaddr, size_t nalign, size_t dim, size_t elemSize ); 8433 8434 forall( T & | sized(T) ) { 8435 // §\CFA§ safe equivalents, i.e., implicit size specification, eliminate return-type cast 8436 T * malloc( void );§\indexc{malloc}§ 8437 T * aalloc( size_t dim );§\indexc{aalloc}§ 8438 T * calloc( size_t dim );§\indexc{calloc}§ 8439 T * resize( T * ptr, size_t size );§\indexc{resize}§ 8440 T * resize( T * ptr, size_t alignment, size_t size ); 8441 T * realloc( T * ptr, size_t size );§\indexc{realloc}§ 8442 T * realloc( T * ptr, size_t alignment, size_t size ); 8443 T * reallocarray( T * ptr, size_t dim );§\indexc{reallocarray}§ 8444 T * reallocarray( T * ptr, size_t alignment, size_t dim ); 8445 T * memalign( size_t align );§\indexc{memalign}§ 8446 T * amemalign( size_t align, size_t dim );§\indexc{amemalign}§ 8447 T * cmemalign( size_t align, size_t dim );§\indexc{aalloc}§ 8448 T * aligned_alloc( size_t align );§\indexc{aligned_alloc}§ 8449 int posix_memalign( T ** ptr, size_t align );§\indexc{posix_memalign}§ 8450 T * valloc( void );§\indexc{valloc}§ 8451 T * pvalloc( void );§\indexc{pvalloc}§ 8113 8452 8114 8453 // §\CFA§ safe general allocation, fill, resize, alignment, array 8115 T * alloc( void );§\indexc{alloc}§ §\C[3.5in]{// variable, T size}§ 8116 T * alloc( size_t dim ); §\C{// array[dim], T size elements}§ 8117 T * alloc( T ptr[], size_t dim ); §\C{// realloc array[dim], T size elements}§ 8118 8119 T * alloc_set( char fill );§\indexc{alloc_set}§ §\C{// variable, T size, fill bytes with value}§ 8120 T * alloc_set( T fill ); §\C{// variable, T size, fill with value}§ 8121 T * alloc_set( size_t dim, char fill ); §\C{// array[dim], T size elements, fill bytes with value}§ 8122 T * alloc_set( size_t dim, T fill ); §\C{// array[dim], T size elements, fill elements with value}§ 8123 T * alloc_set( size_t dim, const T fill[] ); §\C{// array[dim], T size elements, fill elements with array}§ 8124 T * alloc_set( T ptr[], size_t dim, char fill ); §\C{// realloc array[dim], T size elements, fill bytes with value}§ 8125 8126 T * alloc_align( size_t align ); §\C{// aligned variable, T size}§ 8127 T * alloc_align( size_t align, size_t dim ); §\C{// aligned array[dim], T size elements}§ 8128 T * alloc_align( T ptr[], size_t align ); §\C{// realloc new aligned array}§ 8129 T * alloc_align( T ptr[], size_t align, size_t dim ); §\C{// realloc new aligned array[dim]}§ 8130 8131 T * alloc_align_set( size_t align, char fill ); §\C{// aligned variable, T size, fill bytes with value}§ 8132 T * alloc_align_set( size_t align, T fill ); §\C{// aligned variable, T size, fill with value}§ 8133 T * alloc_align_set( size_t align, size_t dim, char fill ); §\C{// aligned array[dim], T size elements, fill bytes with value}§ 8134 T * alloc_align_set( size_t align, size_t dim, T fill ); §\C{// aligned array[dim], T size elements, fill elements with value}§ 8135 T * alloc_align_set( size_t align, size_t dim, const T fill[] ); §\C{// aligned array[dim], T size elements, fill elements with array}§ 8136 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}§ 8137 8138 // §\CFA§ safe initialization/copy, i.e., implicit size specification 8139 T * memset( T * dest, char fill );§\indexc{memset}§ 8140 T * memcpy( T * dest, const T * src );§\indexc{memcpy}§ 8141 8142 // §\CFA§ safe initialization/copy, i.e., implicit size specification, array types 8143 T * amemset( T dest[], char fill, size_t dim ); 8454 T * alloc( ... );§\indexc{alloc}§ §\C{// variable, T size}§ 8455 T * alloc( size_t dim, ... ); 8456 T_align ?`align( size_t alignment );§\indexc{align}§ 8457 T_fill(T) ?`fill( /* various types */ );§\indexc{fill}§ 8458 T_resize ?`resize( void * oaddr );§\indexc{resize}§ 8459 T_realloc ?`realloc( void * oaddr ));§\indexc{realloc}§ 8460 } 8461 8462 forall( T &, List ... ) void free( T * ptr, ... ) // deallocation list 8463 8464 // §\CFA§ allocation/deallocation and constructor/destructor, non-array types 8465 forall( T &, Parms ... | { void ?{}( T &, Parms ); } ) T * new( Parms ... );§\indexc{new}§ 8466 forall( T &, List ... | { void ^?{}( T & ); void delete( List ... ); } );§\indexc{delete}§ 8467 // §\CFA§ allocation/deallocation and constructor/destructor, array types 8468 forall( T & | sized(T), Parms ... | { void ?{}( T &, Parms ); } ) T * anew( size_t dim, Parms ... );§\indexc{anew}§ 8469 forall( T & | sized(T) | { void ^?{}( T & ); }, List ... } ) void adelete( T arr[], List ... );§\indexc{adelete}§ 8470 \end{cfa} 8471 8472 8473 \subsection{Memory Set and Copy} 8474 8475 Like safe memory allocation, \CFA provides safe block initialization and copy. 8476 While objects should be initialized/copied with constructors/assignment, block operations can be very performant. 8477 In certain cases the compiler generates block copy operations, such as assigning structures ©s = t©, however C arrays cannot be assigned. 8478 \begin{cquote} 8479 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8480 struct S { int i, j, k; }; 8481 S s, t, *sp = &s, * tp = &t, sa[10], ta[10]; 8482 \end{cfa} 8483 \noindent 8484 \begin{tabular}{@{}l|l@{}} 8485 \multicolumn{1}{@{}c|}{\textbf{\CFA}} & \multicolumn{1}{c@{}}{\textbf{C}} \\ 8486 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8487 memset( s, '\0' ); 8488 memset( sp, '\0' ); 8489 8490 memcpy( s, t ); 8491 memcpy( sp, tp ); 8492 8493 amemset( sa, '\0', 10 ); 8494 amemcpy( sa, ta, 10 ); 8495 \end{cfa} 8496 & 8497 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8498 memset( &s, '\0', sizeof(s) ); 8499 memset( sp, '\0', sizeof(s) ); 8500 8501 memcpy( &s, &t, sizeof(s) ); 8502 memcpy( sp, tp, sizeof(s) ); 8503 8504 memset( sa, '\0', sizeof(sa) ); 8505 memcpy( sa, ta, sizeof(sa) ); 8506 \end{cfa} 8507 \end{tabular} 8508 \end{cquote} 8509 These operations provide uniformity between reference and pointer, so object dereferencing, '©&©', is unnecessary. 8510 8511 \begin{cfa} 8512 static inline forall( T & | sized(T) ) { 8513 // CFA safe initialization/copy, i.e., implicit size specification, non-array types 8514 T * memset( T * dest, char fill );§\indexc{memset}§ §\C{// all combinations of pointer/reference}§ 8515 T * memset( T & dest, char fill ); 8516 8517 T * memcpy( T * dest, const T * src );§\indexc{memcpy}§ §\C{// all combinations of pointer/reference}§ 8518 T * memcpy( T & dest, const T & src ); 8519 T * memcpy( T * dest, const T & src ); 8520 T * memcpy( T & dest, const T * src ); 8521 8522 // CFA safe initialization/copy, i.e., implicit size specification, array types 8523 T * amemset( T dest[], char fill, size_t dim );§\indexc{memcpy}§ 8144 8524 T * amemcpy( T dest[], const T src[], size_t dim ); 8145 8525 } 8146 8147 // §\CFA§ allocation/deallocation and constructor/destructor, non-array types8148 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );§\indexc{new}§8149 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );§\indexc{delete}§8150 forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } )8151 void delete( T * ptr, Params rest );8152 8153 // §\CFA§ allocation/deallocation and constructor/destructor, array types8154 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );§\indexc{anew}§8155 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );§\indexc{adelete}§8156 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } )8157 void adelete( size_t dim, T arr[], Params rest );8158 8526 \end{cfa} 8159 8527 … … 9290 9658 Int sqrt( Int oper ); 9291 9659 9292 forall( dtype istype| istream( istype ) ) istype * ?|?( istype * is, Int * mp ); §\C{// I/O}§9293 forall( dtype ostype| ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp );9660 forall( istype & | istream( istype ) ) istype * ?|?( istype * is, Int * mp ); §\C{// I/O}§ 9661 forall( ostype & | ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp ); 9294 9662 \end{cfa} 9295 9663 \VRef[Figure]{f:MultiPrecisionFactorials} shows \CFA and C factorial programs using the GMP interfaces. … … 9299 9667 \begin{cquote} 9300 9668 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 9301 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{ C}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{\CFA}} \\9669 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{C}} \\ 9302 9670 \hline 9671 \begin{cfa} 9672 #include <gmp.hfa>§\indexc{gmp}§ 9673 int main( void ) { 9674 sout | "Factorial Numbers"; 9675 ®Int® fact = 1; 9676 9677 sout | 0 | fact; 9678 for ( i; 40 ) { 9679 fact *= i; 9680 sout | i | fact; 9681 } 9682 } 9683 \end{cfa} 9684 & 9303 9685 \begin{cfa} 9304 9686 #include <gmp.h>§\indexc{gmp.h}§ … … 9311 9693 ®mpz_mul_ui®( fact, fact, i ); 9312 9694 ®gmp_printf®( "%d %Zd\n", i, fact ); 9313 }9314 }9315 \end{cfa}9316 &9317 \begin{cfa}9318 #include <gmp.hfa>§\indexc{gmp}§9319 int main( void ) {9320 sout | "Factorial Numbers";9321 Int fact = 1;9322 9323 sout | 0 | fact;9324 for ( i; 40 ) {9325 fact *= i;9326 sout | i | fact;9327 9695 } 9328 9696 } … … 9419 9787 Rational narrow( double f, long int md ); 9420 9788 9421 forall( dtype istype| istream( istype ) ) istype * ?|?( istype *, Rational * ); // I/O9422 forall( dtype ostype| ostream( ostype ) ) ostype * ?|?( ostype *, Rational );9789 forall( istype & | istream( istype ) ) istype * ?|?( istype *, Rational * ); // I/O 9790 forall( ostype & | ostream( ostype ) ) ostype * ?|?( ostype *, Rational ); 9423 9791 \end{cfa} 9424 9792 … … 9440 9808 \end{document} 9441 9809 9810 From: Michael Leslie Brooks <mlbrooks@uwaterloo.ca> 9811 To: Peter Buhr <pabuhr@uwaterloo.ca>, 9812 Andrew James Beach 9813 <ajbeach@uwaterloo.ca>, 9814 Fangren Yu <f37yu@uwaterloo.ca>, Jiada Liang 9815 <j82liang@uwaterloo.ca> 9816 Subject: The White House on Memory-Safe programming 9817 Date: Mon, 4 Mar 2024 16:49:53 +0000 9818 9819 I heard tell of this announcement last night. Haven't read the actual report yet. 9820 9821 Most mainstream article I can find: https://me.pcmag.com/en/security/22413/white-house-to-developers-using-c-or-c-invites-cybersecurity-risks 9822 Less fluffy summary: https://www.developer-tech.com/news/2024/feb/27/white-house-urges-adoption-memory-safe-programming-languages/ 9823 Horse's Mouth: https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf 9824 "This report focuses on the programming language as a primary building block, and explores hardware architecture and formal methods as complementary approaches" 9825 9826 A contrary analysis: https://hackaday.com/2024/02/29/the-white-house-memory-safety-appeal-is-a-security-red-herring/ 9827 9442 9828 % Local Variables: % 9443 9829 % tab-width: 4 %
Note:
See TracChangeset
for help on using the changeset viewer.