Changeset 33218c6 for doc/user/user.tex
- Timestamp:
- Jul 26, 2017, 12:19:41 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- b947fb2
- Parents:
- e0a653d (diff), ea91c42 (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
-
doc/user/user.tex (modified) (48 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
re0a653d r33218c6 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Fri Jul 7 10:36:39 201714 %% Update Count : 2 54713 %% Last Modified On : Sat Jul 22 11:01:19 2017 14 %% Update Count : 2878 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 57 57 \CFAStyle % use default CFA format-style 58 58 59 \lstnewenvironment{C++}[1][] 60 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®}#1}} 61 {} 62 59 63 % inline code ©...© (copyright symbol) emacs: C-q M-) 60 64 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. … … 137 141 138 142 \CFA{}\index{cforall@\CFA}\footnote{Pronounced ``\Index*{C-for-all}'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed as an evolutionary step forward for the C programming language. 139 The syntax of the \CFA language builds from C,and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.143 The syntax of \CFA builds from C and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers. 140 144 % Any language feature that is not described here can be assumed to be using the standard \Celeven syntax. 141 \CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving Cperformance.142 Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible.145 \CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving similar performance. 146 Like C, \CFA is a statically typed, procedural (non-\Index{object-oriented}) language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible. 143 147 The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules. 144 148 145 One of the main design philosophies of \CFA is to ``describe not prescribe'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''. 146 Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming features. 147 A programmer is always free to reach back to C from \CFA for any reason, and in many cases, new \CFA features have a fallback to a C mechanism. 148 There is no notion or requirement for rewriting a legacy C program in \CFA; 149 instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features. 150 New programs can be written in \CFA using a combination of C and \CFA features. 151 \Index*[C++]{\CC{}} had a similar goal 30 years ago, but currently has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project. 149 One of the main design philosophies of \CFA is to ``\Index{describe not prescribe}'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''. 150 Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming. 151 A programmer is always free to reach back to C from \CFA, for any reason, and in many cases, new \CFA features can be locally switched back to there C counterpart. 152 There is no notion or requirement for \emph{rewriting} a legacy C program in \CFA; 153 instead, a programmer evolves a legacy program into \CFA by incrementally incorporating \CFA features. 154 As well, new programs can be written in \CFA using a combination of C and \CFA features. 155 156 \Index*[C++]{\CC{}} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C. 157 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, all of which requires significant effort and training to incrementally add \CC to a C-based project. 152 158 In contrast, \CFA has 30 years of hindsight and a clean starting point. 153 159 … … 156 162 \begin{quote2} 157 163 \begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}} 158 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 159 \begin{cfa} 160 #include <fstream>§\indexc{fstream}§ 161 162 int main( void ) { 163 int x = 0, y = 1, z = 2; 164 ®sout | x | y | z | endl;® 165 } 166 \end{cfa} 167 & 168 \begin{lstlisting} 164 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 165 \begin{cfa} 169 166 #include <stdio.h>§\indexc{stdio.h}§ 170 167 … … 173 170 ®printf( "%d %d %d\n", x, y, z );® 174 171 } 175 \end{ lstlisting}172 \end{cfa} 176 173 & 177 \begin{lstlisting} 174 \begin{cfa} 175 #include <fstream>§\indexc{fstream}§ 176 177 int main( void ) { 178 int x = 0, y = 1, z = 2; 179 ®sout | x | y | z | endl;®§\indexc{sout}§ 180 } 181 \end{cfa} 182 & 183 \begin{cfa} 178 184 #include <iostream>§\indexc{iostream}§ 179 185 using namespace std; … … 182 188 ®cout<<x<<" "<<y<<" "<<z<<endl;® 183 189 } 184 \end{ lstlisting}190 \end{cfa} 185 191 \end{tabular} 186 192 \end{quote2} 187 193 While the \CFA I/O looks similar to the \Index*[C++]{\CC{}} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}). 188 194 195 \subsection{Background} 196 189 197 This document is a programmer reference-manual for the \CFA programming language. 190 198 The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature. 191 199 The manual does not teach programming, i.e., how to combine the new constructs to build complex programs. 192 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented as well as some experience programming in C/\CC.193 Implementers mayrefer to the \CFA Programming Language Specification for details about the language syntax and semantics.200 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC. 201 Implementers should refer to the \CFA Programming Language Specification for details about the language syntax and semantics. 194 202 Changes to the syntax and additional features are expected to be included in later revisions. 195 203 … … 200 208 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 201 209 Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction. 202 For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually thelanguage of choice.210 For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is usually the only language of choice. 203 211 The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC{}} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% each with a long tail. 204 212 As well, for 30 years, C has been the number 1 and 2 most popular programming language: … … 216 224 \end{center} 217 225 Hence, C is still an extremely important programming language, with double the usage of \Index*[C++]{\CC{}}; in many cases, \CC is often used solely as a better C. 218 Love it or hate it, C has been an important and influential part of computer science for 40 years and sitappeal is not diminishing.219 Unfortunately, C has too many problems and omissions to make it anacceptable programming language for modern needs.220 221 As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way.226 Love it or hate it, C has been an important and influential part of computer science for 40 years and its appeal is not diminishing. 227 Unfortunately, C has many problems and omissions that make it an unacceptable programming language for modern needs. 228 229 As stated, the goal of the \CFA project is to engineer modern language-features into C in an evolutionary rather than revolutionary way. 222 230 \CC~\cite{C++14,C++} is an example of a similar project; 223 however, it largely extended the language, and did not address manyexisting problems.\footnote{%231 however, it largely extended the C language, and did not address most of C's existing problems.\footnote{% 224 232 Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.} 225 \Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.233 \Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language. 226 234 \Index*{Java}~\cite{Java8}, \Index*{Go}~\cite{Go}, \Index*{Rust}~\cite{Rust} and \Index*{D}~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent. 227 These languages have different syntax and semantics from C, and do not interoperate directly with C, largely because ofgarbage collection.235 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection. 228 236 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten. 229 These costs can be prohibitive for many companies with a large software base in C/\CC, and a significant number of programmers requiring retraining to anew programming language.230 231 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fix ing some of the well known C problems and containing many modern languagefeatures.237 These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining to the new programming language. 238 239 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while containing modern language-features. 232 240 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 233 241 as a result, it will fade into disuse. 234 242 Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language. 235 While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features.236 While some may argue that modern language features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today.243 While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language-features. 244 While some may argue that modern language-features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today. 237 245 238 246 239 247 \section{History} 240 248 241 The \CFA project started with \Index*{K-W C}~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and extended assignment capabilities using the notion of tuples.249 The \CFA project started with \Index*{K-W C}~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and advanced assignment capabilities using the notion of tuples. 242 250 (See~\cite{Werther96} for similar work in \Index*[C++]{\CC{}}.) 243 A first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}. 244 The signature feature of \CFA is parametric-polymorphic functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name): 251 The first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}. 252 253 The signature feature of \CFA is \emph{\Index{overload}able} \Index{parametric-polymorphic} functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name): 245 254 \begin{lstlisting} 246 255 ®forall( otype T )® T identity( T val ) { return val; } … … 248 257 \end{lstlisting} 249 258 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. 250 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfi led~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.259 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfield~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}. 251 260 However, at that time, there was little interesting in extending C, so work did not continue. 252 As the saying goes, `` What goes around, comes around.'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.261 As the saying goes, ``\Index*{What goes around, comes around.}'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted. 253 262 254 263 … … 257 266 258 267 \CFA is designed to integrate directly with existing C programs and libraries. 259 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no overhead to call existing C routines.268 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no complex interface or overhead to call existing C routines. 260 269 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features. 261 270 Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself. 262 271 Fortunately, \CFA, like \Index*[C++]{\CC{}}, starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at very low cost. 263 Hence, \CFA begins by leveraging the large repository of C libraries with little cost.272 Hence, \CFA begins by leveraging the large repository of C libraries, and than allows programmers to incrementally augment their C programs with modern \Index{backward-compatible} features. 264 273 265 274 \begin{comment} … … 304 313 \end{comment} 305 314 306 However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC.315 However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC. 307 316 For example, the C math-library provides the following routines for computing the absolute value of the basic types: ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©. 308 Whereas, \CFA wraps each of these routines into ones with the commonname ©abs©:317 Whereas, \CFA wraps each of these routines into ones with the overloaded name ©abs©: 309 318 \begin{cfa} 310 319 char abs( char ); 311 ®extern "C" {® 312 int abs( int ); §\C{// use default C routine for int}§ 313 ®}® // extern "C" 320 ®extern "C" {® int abs( int ); ®}® §\C{// use default C routine for int}§ 314 321 long int abs( long int ); 315 322 long long int abs( long long int ); … … 326 333 Hence, there is the same need as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed. 327 334 There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type. 328 This example strongly illustrates a core idea in \CFA: \emph{the power of a name}. 335 336 This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}. 329 337 The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value. 330 Hence, knowing the name ©abs© should besufficient to apply it to any type where it is applicable.331 The time savings and safety of using one name uniformly versus $N$ unique names shouldnot be underestimated.332 333 334 \section[Compiling CFA Program]{Compiling\CFA Program}335 336 The command ©cfa© is used to compile \CFA program(s), and is based on the GNU\Indexc{gcc} command, \eg:337 \begin{cfa} 338 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA §-files [ assembler/loader-files ]338 Hence, knowing the name ©abs© is sufficient to apply it to any type where it is applicable. 339 The time savings and safety of using one name uniformly versus $N$ unique names cannot be underestimated. 340 341 342 \section[Compiling a CFA Program]{Compiling a \CFA Program} 343 344 The command ©cfa© is used to compile a \CFA program and is based on the \Index{GNU} \Indexc{gcc} command, \eg: 345 \begin{cfa} 346 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA{}§-files [ assembler/loader-files ] 339 347 \end{cfa} 340 348 \CFA programs having the following ©gcc© flags turned on: … … 344 352 The 1999 C standard plus GNU extensions. 345 353 \item 346 {\lstset{deletekeywords={inline}} 347 \Indexc{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{©-fgnu89-inline©}} 354 \Indexc[deletekeywords=inline]{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{\lstinline[deletekeywords=inline]$-fgnu89-inline$}} 348 355 Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files. 349 }%350 356 \end{description} 351 357 The following new \CFA options are available: … … 354 360 \Indexc{-CFA}\index{compilation option!-CFA@©-CFA©} 355 361 Only the C preprocessor and the \CFA translator steps are performed and the transformed program is written to standard output, which makes it possible to examine the code generated by the \CFA translator. 356 The generated code start ed with the standard \CFA prelude.362 The generated code starts with the standard \CFA \Index{prelude}. 357 363 358 364 \item 359 365 \Indexc{-debug}\index{compilation option!-debug@©-debug©} 360 366 The program is linked with the debugging version of the runtime system. 361 The debug version performs runtime checks to help during the debugging phase of a \CFA program, but substantially slows the execution of the program.367 The debug version performs runtime checks to help during the debugging phase of a \CFA program, but can substantially slow program execution. 362 368 The runtime checks should only be removed after the program is completely debugged. 363 369 \textbf{This option is the default.} … … 366 372 \Indexc{-nodebug}\index{compilation option!-nodebug@©-nodebug©} 367 373 The program is linked with the non-debugging version of the runtime system, so the execution of the program is faster. 368 \Emph{However, no runtime checks or ©assert©s are performed so errors usually result in abnormal program termination.}374 \Emph{However, no runtime checks or ©assert©s are performed so errors usually result in abnormal program behaviour or termination.} 369 375 370 376 \item … … 386 392 \textbf{This option is the default.} 387 393 394 \begin{comment} 388 395 \item 389 396 \Indexc{-no-include-stdhdr}\index{compilation option!-no-include-stdhdr@©-no-include-stdhdr©} 390 397 Do not supply ©extern "C"© wrappers for \Celeven standard include files (see~\VRef{s:StandardHeaders}). 391 398 \textbf{This option is \emph{not} the default.} 399 \end{comment} 392 400 \end{description} 393 401 … … 410 418 \item 411 419 \Indexc{__CFA__}\index{preprocessor variables!__CFA__@©__CFA__©}, 412 \Indexc{__CFORALL__}\index{preprocessor variables!__CFORALL__@©__CFORALL__©} and420 \Indexc{__CFORALL__}\index{preprocessor variables!__CFORALL__@©__CFORALL__©}, and 413 421 \Indexc{__cforall}\index{preprocessor variables!__cforall@©__cforall©} 414 422 are always available during preprocessing and have no value. 415 423 \end{description} 416 424 These preprocessor variables allow conditional compilation of programs that must work differently in these situations. 417 For example, to toggle between C and \CFA extensions, us ingthe following:425 For example, to toggle between C and \CFA extensions, use the following: 418 426 \begin{cfa} 419 427 #ifndef __CFORALL__ … … 426 434 427 435 428 \section{Constant sUnderscores}429 430 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg:436 \section{Constant Underscores} 437 438 Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg: 431 439 \begin{cfa} 432 440 2®_®147®_®483®_®648; §\C{// decimal constant}§ … … 441 449 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 442 450 \end{cfa} 443 The rules for placement of underscores is as follows:444 \begin{enumerate} 451 The rules for placement of underscores are: 452 \begin{enumerate}[topsep=5pt,itemsep=5pt,parsep=0pt] 445 453 \item 446 454 A sequence of underscores is disallowed, \eg ©12__34© is invalid. … … 463 471 \label{s:BackquoteIdentifiers} 464 472 465 \CFA accommodates keyword clashes with existing C variable-names by syntactic transformations using the \CFA backquote escape-mechanism: 473 \CFA introduces several new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code. 474 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism: 466 475 \begin{cfa} 467 476 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ 468 477 double ®`®forall®`® = 3.5; 469 478 \end{cfa} 479 470 480 Existing C programs with keyword clashes can be converted by enclosing keyword identifiers in backquotes, and eventually the identifier name can be changed to a non-keyword name. 471 \VRef[Figure]{f:InterpositionHeaderFile} shows how clashes in C header files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©: 481 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©. 482 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience. 472 483 473 484 \begin{figure} 474 485 \begin{cfa} 475 // include file uses the CFA keyword " otype".476 #if ! defined( otype) §\C{// nesting ?}§477 #define otype ®`®otype®`®§\C{// make keyword an identifier}§486 // include file uses the CFA keyword "with". 487 #if ! defined( with ) §\C{// nesting ?}§ 488 #define with ®`®with®`® §\C{// make keyword an identifier}§ 478 489 #define __CFA_BFD_H__ 479 #endif // ! otype480 481 #®include_next® <bfd.h>§\C{// must have internal check for multiple expansion}§482 483 #if defined( otype) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§484 #undef otype490 #endif 491 492 ®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§ 493 ® 494 #if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§ 495 #undef with 485 496 #undef __CFA_BFD_H__ 486 #endif // otype && __CFA_BFD_H__487 \end{cfa} 488 \caption{ Interposition of Header File}489 \label{f: InterpositionHeaderFile}497 #endif 498 \end{cfa} 499 \caption{Header-File Interposition} 500 \label{f:HeaderFileInterposition} 490 501 \end{figure} 491 502 492 503 493 \section{ Labelled Continue/Break}504 \section{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break}}{Labelled continue / break}} 494 505 495 506 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 496 507 Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting. 497 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85 ,Java}.508 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java. 498 509 For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement; 499 510 for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement. … … 512 523 ®LF:® for ( ... ) { 513 524 ®LW:® while ( ... ) { 514 ... break ®LC®; ... // terminate compound515 ... break ®LS®; ... // terminate switch516 ... break ®LIF®; ... // terminate if517 ... continue ®LF;® ... // resume loop518 ... break ®LF®; ... // terminate loop519 ... continue ®LW®; ... // resume loop520 ... break ®LW®; ... // terminate loop525 ... break ®LC®; ... // terminate compound 526 ... break ®LS®; ... // terminate switch 527 ... break ®LIF®; ... // terminate if 528 ... continue ®LF;® ... // resume loop 529 ... break ®LF®; ... // terminate loop 530 ... continue ®LW®; ... // resume loop 531 ... break ®LW®; ... // terminate loop 521 532 } // while 522 533 } // for 523 534 } else { 524 ... break ®LIF®; ... // terminate if535 ... break ®LIF®; ... // terminate if 525 536 } // if 526 537 } // switch … … 564 575 LF: for ( ;; ) { 565 576 LW: while ( 1 ) { 566 break LC; // terminate compound567 break LS; // terminate switch568 break LIF; // terminate if569 continue LF; // resume loop570 break LF; // terminate loop571 continue LW; // resume loop572 break LW; // terminate loop577 break LC; // terminate compound 578 break LS; // terminate switch 579 break LIF; // terminate if 580 continue LF; // resume loop 581 break LF; // terminate loop 582 continue LW; // resume loop 583 break LW; // terminate loop 573 584 } // while 574 585 } // for 575 586 } else { 576 break LIF; // terminate if587 break LIF; // terminate if 577 588 } // if 578 589 } // switch … … 613 624 \item 614 625 They cannot branch into a control structure. 615 This restriction prevents missing initializationat the start of a control structure resulting in undefined behaviour.626 This restriction prevents missing declarations and/or initializations at the start of a control structure resulting in undefined behaviour. 616 627 \end{itemize} 617 628 The advantage of the labelled ©continue©/©break© is allowing static multi-level exits without having to use the ©goto© statement, and tying control flow to the target control structure rather than an arbitrary point in a program. 618 Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader that complex control-flow is occurring in the body of the control structure.629 Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader (\Index{eye candy}) that complex control-flow is occurring in the body of the control structure. 619 630 With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader. 620 631 Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs. … … 622 633 623 634 624 \section{ Switch Statement}635 \section{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}} 625 636 626 637 C allows a number of questionable forms for the ©switch© statement: … … 663 674 ®// open input file 664 675 ®} else if ( argc == 2 ) { 665 ®// open input file 676 ®// open input file (duplicate) 666 677 667 678 ®} else { … … 676 687 \begin{cfa} 677 688 switch ( i ) { 678 case 1: case 3: case 5:// odd values679 // sameaction689 ®case 1: case 3: case 5:® // odd values 690 // odd action 680 691 break; 681 case 2: case 4: case 6:// even values682 // sameaction692 ®case 2: case 4: case 6:® // even values 693 // even action 683 694 break; 684 695 } … … 686 697 However, this situation is handled in other languages without fall-through by allowing a list of case values. 687 698 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from virtually all other programming languages with a ©switch© statement. 688 Hence, default fall-through semantics results in a large number of programming errors as programmers often forgetthe ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.699 Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 689 700 690 701 \item … … 708 719 The problem with this usage is branching into control structures, which is known to cause both comprehension and technical difficulties. 709 720 The comprehension problem occurs from the inability to determine how control reaches a particular point due to the number of branches leading to it. 710 The technical problem results from the inability to ensure allocation and initialization of variables when blocks are not entered at the beginning. 711 Often transferring into a block can bypass variable declaration and/or its initialization, which results in subsequent errors. 712 There are virtually no positive arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it. 721 The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning. 722 There are no positive arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it. 713 723 Nevertheless, C does have an idiom where this capability is used, known as ``\Index*{Duff's device}''~\cite{Duff83}: 714 724 \begin{cfa} … … 770 780 and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound. 771 781 \end{itemize} 772 These observations help to put the \CFA changes to the ©switch© into perspective.782 These observations put into perspective the \CFA changes to the ©switch©. 773 783 \begin{enumerate} 774 784 \item … … 791 801 case 7: 792 802 ... 793 ®break® §\C{// explicit end of switch}§803 ®break® §\C{// redundant explicit end of switch}§ 794 804 default: 795 805 j = 3; … … 797 807 \end{cfa} 798 808 Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses; 799 theimplicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.800 Theexplicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.809 An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause. 810 An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement. 801 811 As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers. 802 812 \item … … 827 837 828 838 829 \section{ Case Clause}839 \section{\texorpdfstring{\LstKeywordStyle{case} Clause}{case Clause}} 830 840 831 841 C restricts the ©case© clause of a ©switch© statement to a single value. … … 903 913 904 914 915 \section{\texorpdfstring{\LstKeywordStyle{with} Clause / Statement}{with Clause / Statement}} 916 \label{s:WithClauseStatement} 917 918 In \Index{object-oriented} programming, there is an implicit first parameter, often names \textbf{©self©} or \textbf{©this©}, which is elided. 919 \begin{C++} 920 class C { 921 int i, j; 922 int mem() { ®// implicit "this" parameter 923 ® i = 1; ®// this->i 924 ® j = 3; ®// this->j 925 ® } 926 } 927 \end{C++} 928 Since CFA is non-object-oriented, the equivalent object-oriented program looks like: 929 \begin{cfa} 930 struct S { int i, j; }; 931 int mem( S &this ) { // explicit "this" parameter 932 ®this.®i = 1; // "this" is not elided 933 ®this.®j = 2; 934 } 935 \end{cfa} 936 but it is cumbersome having to write "©this.©" many times in a member. 937 938 \CFA provides a ©with© clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided the "©this.©" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references. 939 \begin{cfa} 940 int mem( S &this ) ®with this® { // with clause 941 i = 1; ®// this.i 942 ® j = 2; ®// this.j 943 ®} 944 \end{cfa} 945 which extends to multiple routine parameters: 946 \begin{cfa} 947 struct T { double m, n; }; 948 int mem2( S &this1, T &this2 ) ®with this1, this2® { 949 i = 1; j = 2; 950 m = 1.0; n = 2.0; 951 } 952 \end{cfa} 953 954 The statement form is used within a block: 955 \begin{cfa} 956 int foo() { 957 struct S1 { ... } s1; 958 struct S2 { ... } s2; 959 ®with s1® { // with statement 960 // access fields of s1 without qualification 961 ®with s2® { // nesting 962 // access fields of s1 and s2 without qualification 963 } 964 } 965 ®with s1, s2® { 966 // access unambiguous fields of s1 and s2 without qualification 967 } 968 } 969 \end{cfa} 970 971 When opening multiple structures, fields with the same name and type are ambiguous and must be fully qualified. 972 For fields with the same name but different type, context/cast can be used to disambiguate. 973 \begin{cfa} 974 struct S { int i; int j; double m; } a, c; 975 struct T { int i; int k; int m } b, c; 976 ®with a, b® { 977 j + k; §\C{// unambiguous, unique names define unique types}§ 978 i; §\C{// ambiguous, same name and type}§ 979 a.i + b.i; §\C{// unambiguous, qualification defines unique names}§ 980 m; §\C{// ambiguous, same name and no context to define unique type}§ 981 m = 5.0; §\C{// unambiguous, same name and context defines unique type}§ 982 m = 1; §\C{// unambiguous, same name and context defines unique type}§ 983 } 984 ®with c® { ... } §\C{// ambiguous, same name and no context}§ 985 ®with (S)c® { ... } §\C{// unambiguous, same name and cast defines unique type}§ 986 \end{cfa} 987 988 905 989 \section{Exception Handling} 990 \label{s:ExceptionHandling} 906 991 907 992 Exception handling provides two mechanism: change of control flow from a raise to a handler, and communication from the raise to the handler. 908 \begin{cfa} 909 exception void h( int i ); 910 exception int h( int i, double d ); 911 993 Transfer of control can be local, within a routine, or non-local, among routines. 994 Non-local transfer can cause stack unwinding, i.e., non-local routine termination, depending on the kind of raise. 995 \begin{cfa} 996 exception_t E {}; §\C{// exception type}§ 912 997 void f(...) { 913 ... throw h( 3 ); 914 ... i = resume h( 3, 5.1 ); 915 } 916 998 ... throw E{}; ... §\C{// termination}§ 999 ... throwResume E{}; ... §\C{// resumption}§ 1000 } 917 1001 try { 918 1002 f(...); 919 } catch h( int w ) {920 // re set921 } resume h( int p, double x ) {922 return 17; // recover1003 } catch( E e : §boolean-predicate§ ) { §\C{// termination handler}§ 1004 // recover and continue 1005 } catchResume( E e : §boolean-predicate§ ) { §\C{// resumption handler}§ 1006 // repair and return 923 1007 } finally { 924 } 925 \end{cfa} 926 So the type raised would be the mangled name of the exception prototype and that name would be matched at the handler clauses by comparing the strings. 927 The arguments for the call would have to be packed in a message and unpacked at handler clause and then a call made to the handler. 1008 // always executed 1009 } 1010 \end{cfa} 1011 The kind of raise and handler match: ©throw© with ©catch© and ©throwResume© with ©catchResume©. 1012 Then the exception type must match along with any additonal predicate must be true. 1013 The ©catch© and ©catchResume© handlers may appear in any oder. 1014 However, the ©finally© clause must appear at the end of the ©try© statement. 928 1015 929 1016 … … 1136 1223 1137 1224 1138 \section{Pointer/Reference} 1225 \section{Exponentiation Operator} 1226 1227 C, \CC, and Java (and many other programming languages) have no exponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow}, to perform the exponentiation operation. 1228 \CFA extends the basic operators with the exponentiation operator ©?\?©\index{?\\?@\lstinline$?\?$} and ©?\=?©\index{?\\=?@\lstinline$?\=?$}, as in, ©x \ y© and ©x \= y©, which means $x^y$ and $x \leftarrow x^y$. 1229 The priority of the exponentiation operator is between the cast and multiplicative operators, so that ©w * (int)x \ (int)y * z© is parenthesized as ©((w * (((int)x) \ ((int)y))) * z)©. 1230 1231 As for \Index{division}, there are exponentiation operators for integral and floating-point types, including the builtin \Index{complex} types. 1232 Unsigned integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication (or shifting if the base is 2). 1233 Signed integral exponentiation\index{exponentiation!signed integral} is performed with repeated multiplication (or shifting if the base is 2), but yields a floating-point result because $b^{-e}=1/b^e$. 1234 Hence, it is important to designate exponent integral-constants as unsigned or signed: ©3 \ 3u© return an integral result, while ©3 \ 3© returns a floating-point result. 1235 Floating-point exponentiation\index{exponentiation!floating point} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the base cannot be negative. 1236 \begin{cfa} 1237 sout | 2 ®\® 8u | 4 ®\® 3u | -4 ®\® 3u | 4 ®\® -3 | -4 ®\® -3 | 4.0 ®\® 2.1 | (1.0f+2.0fi) ®\® (3.0f+2.0fi) | endl; 1238 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i 1239 \end{cfa} 1240 Parenthesis are necessary for the complex constants or the expresion is parsed as ©1.0f+(2.0fi \ 3.0f)+2.0fi©. 1241 The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation versions are available. 1242 For returning an integral value, the user type ©T© must define multiplication, ©*©, and one, ©1©; 1243 for returning a floating-point value, an additional divide of type ©T© into a ©double© returning a ©double© (©double ?/?( double, T )©) is necessary for negative exponents. 1244 1245 1246 \section{Pointer / Reference} 1139 1247 1140 1248 C provides a \newterm{pointer type}; … … 1144 1252 An integer constant expression with the value 0, or such an expression cast to type ©void *©, is called a \newterm{null-pointer constant}.\footnote{ 1145 1253 One way to conceptualize the null pointer is that no variable is placed at this address, so the null-pointer address can be used to denote an uninitialized pointer/reference object; 1146 \ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine.} 1254 \ie the null pointer is guaranteed to compare unequal to a pointer to any object or routine. 1255 In general, a value with special meaning among a set of values is called a \emph{\Index{sentinel value}}, \eg ©-1© as a return code value.} 1147 1256 An address is \newterm{sound}, if it points to a valid memory location in scope, \ie within the program's execution-environment and has not been freed. 1148 1257 Dereferencing an \newterm{unsound} address, including the null pointer, is \Index{undefined}, often resulting in a \Index{memory fault}. … … 1179 1288 \hline 1180 1289 \begin{cfa} 1181 lda r1,100 // load address of x1182 ld r2,(r1) // load value of x1183 lda r3,104 // load address of y1184 st r2,(r3) // store x into y1290 lda r1,100 // load address of x 1291 ld r2,(r1) // load value of x 1292 lda r3,104 // load address of y 1293 st r2,(r3) // store x into y 1185 1294 \end{cfa} 1186 1295 & 1187 1296 \begin{cfa} 1188 1297 1189 ld r2,(100) // load value of x1190 1191 st r2,(104) // store x into y1298 ld r2,(100) // load value of x 1299 1300 st r2,(104) // store x into y 1192 1301 \end{cfa} 1193 1302 \end{tabular} … … 1485 1594 1486 1595 \item 1487 lvalue to reference conversion: \lstinline[deletekeywords= {lvalue}]@lvalue-type cv1 T@converts to ©cv2 T &©, which allows implicitly converting variables to references.1596 lvalue to reference conversion: \lstinline[deletekeywords=lvalue]$lvalue-type cv1 T$ converts to ©cv2 T &©, which allows implicitly converting variables to references. 1488 1597 \begin{cfa} 1489 1598 int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &) … … 2594 2703 \begin{cfa}[belowskip=0pt] 2595 2704 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§ 2596 strcpy( store, sepGet( sout ) ); 2597 sepSet( sout, "_" ); 2705 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§ 2706 sepSet( sout, "_" ); §\C{// change separator to underscore}§ 2598 2707 sout | 1 | 2 | 3 | endl; 2599 2708 \end{cfa} … … 2602 2711 \end{cfa} 2603 2712 \begin{cfa}[belowskip=0pt] 2604 sepSet( sout, store ); 2713 sepSet( sout, store ); §\C{// change separator back to original}§ 2605 2714 sout | 1 | 2 | 3 | endl; 2606 2715 \end{cfa} … … 3159 3268 \Indexc{gcc} provides ©typeof© to declare a secondary variable from a primary variable. 3160 3269 \CFA also relies heavily on the specification of the left-hand side of assignment for type inferencing, so in many cases it is crucial to specify the type of the left-hand side to select the correct type of the right-hand expression. 3161 Only for overloaded routines with the same return typeis variable type-inferencing possible.3270 Only for overloaded routines \emph{with the same return type} is variable type-inferencing possible. 3162 3271 Finally, ©auto© presents the programming problem of tracking down a type when the type is actually needed. 3163 3272 For example, given … … 5258 5367 5259 5368 5260 \section{\ CFA Keywords}5369 \section{\texorpdfstring{\CFA Keywords}{Cforall Keywords}} 5261 5370 \label{s:CFAKeywords} 5262 5371 5372 \CFA introduces the following new keywords. 5373 5263 5374 \begin{quote2} 5264 \begin{tabular}{llll }5375 \begin{tabular}{lllll} 5265 5376 \begin{tabular}{@{}l@{}} 5266 ©_A T© \\5377 ©_At© \\ 5267 5378 ©catch© \\ 5268 5379 ©catchResume© \\ 5269 5380 ©choose© \\ 5270 5381 ©coroutine© \\ 5271 ©disable© \\5272 5382 \end{tabular} 5273 5383 & 5274 5384 \begin{tabular}{@{}l@{}} 5385 ©disable© \\ 5275 5386 ©dtype© \\ 5276 5387 ©enable© \\ 5277 5388 ©fallthrough© \\ 5278 5389 ©fallthru© \\ 5279 ©finally© \\5280 ©forall© \\5281 5390 \end{tabular} 5282 5391 & 5283 5392 \begin{tabular}{@{}l@{}} 5393 ©finally© \\ 5394 ©forall© \\ 5284 5395 ©ftype© \\ 5285 5396 ©lvalue© \\ 5286 5397 ©monitor© \\ 5398 \end{tabular} 5399 & 5400 \begin{tabular}{@{}l@{}} 5287 5401 ©mutex© \\ 5288 5402 ©one_t© \\ 5289 5403 ©otype© \\ 5404 ©throw© \\ 5405 ©throwResume© \\ 5290 5406 \end{tabular} 5291 5407 & 5292 5408 \begin{tabular}{@{}l@{}} 5293 ©throw© \\5294 ©throwResume© \\5295 5409 ©trait© \\ 5296 5410 ©try© \\ 5297 5411 ©ttype© \\ 5412 ©with© \\ 5298 5413 ©zero_t© \\ 5299 5414 \end{tabular} … … 5330 5445 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 5331 5446 \end{cfa} 5332 \CFA supportsK\&R routine definitions:5447 \CFA continues to support K\&R routine definitions: 5333 5448 \begin{cfa} 5334 5449 f( a, b, c ) §\C{// default int return}§ … … 5471 5586 \Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list: 5472 5587 \begin{quote2} 5473 \lstset{deletekeywords={float}} 5474 \begin{tabular}{@{}llll|l@{}} 5475 \multicolumn{4}{c|}{C11} & \multicolumn{1}{c}{\CFA} \\ 5588 \begin{tabular}{@{}lllll|l@{}} 5589 \multicolumn{5}{c|}{C11} & \multicolumn{1}{c}{\CFA} \\ 5476 5590 \hline 5477 5591 \begin{tabular}{@{}l@{}} … … 5481 5595 \Indexc{errno.h} \\ 5482 5596 \Indexc{fenv.h} \\ 5483 \Indexc{float.h} \\ 5484 \Indexc{inttypes.h} \\ 5485 \Indexc{iso646.h} \\ 5597 \Indexc[deletekeywords=float]{float.h} \\ 5486 5598 \end{tabular} 5487 5599 & 5488 5600 \begin{tabular}{@{}l@{}} 5601 \Indexc{inttypes.h} \\ 5602 \Indexc{iso646.h} \\ 5489 5603 \Indexc{limits.h} \\ 5490 5604 \Indexc{locale.h} \\ 5491 5605 \Indexc{math.h} \\ 5492 5606 \Indexc{setjmp.h} \\ 5607 \end{tabular} 5608 & 5609 \begin{tabular}{@{}l@{}} 5493 5610 \Indexc{signal.h} \\ 5494 5611 \Indexc{stdalign.h} \\ 5495 5612 \Indexc{stdarg.h} \\ 5496 5613 \Indexc{stdatomic.h} \\ 5614 \Indexc{stdbool.h} \\ 5615 \Indexc{stddef.h} \\ 5497 5616 \end{tabular} 5498 5617 & 5499 5618 \begin{tabular}{@{}l@{}} 5500 \Indexc{stdbool.h} \\5501 \Indexc{stddef.h} \\5502 5619 \Indexc{stdint.h} \\ 5503 5620 \Indexc{stdio.h} \\ … … 5515 5632 \Indexc{wctype.h} \\ 5516 5633 \\ 5517 \\5518 \\5519 5634 \end{tabular} 5520 5635 & … … 5522 5637 \Indexc{unistd.h} \\ 5523 5638 \Indexc{gmp.h} \\ 5524 \\5525 \\5526 5639 \\ 5527 5640 \\ … … 5563 5676 The table shows allocation routines supporting different combinations of storage-management capabilities: 5564 5677 \begin{center} 5565 \begin{tabular}{@{} lr|l|l|l|l@{}}5566 && \multicolumn{1}{c|}{fill} & resize & alignment & array \\5678 \begin{tabular}{@{}r|r|l|l|l|l@{}} 5679 \multicolumn{1}{c}{}& & \multicolumn{1}{c|}{fill} & resize & alignment & array \\ 5567 5680 \hline 5568 5681 C & ©malloc© & no & no & no & no \\ … … 5571 5684 & ©memalign© & no & no & yes & no \\ 5572 5685 & ©posix_memalign© & no & no & yes & no \\ 5686 \hline 5573 5687 C11 & ©aligned_alloc© & no & no & yes & no \\ 5688 \hline 5574 5689 \CFA & ©alloc© & no/copy/yes & no/yes & no & yes \\ 5575 5690 & ©align_alloc© & no/yes & no & yes & yes \\
Note:
See TracChangeset
for help on using the changeset viewer.