Changes in doc/proposals/enum.tex [d63746f:bd67442]
- File:
-
- 1 edited
-
doc/proposals/enum.tex (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
rd63746f rbd67442 117 117 \end{abstract} 118 118 119 \section{ Introduction}119 \section{Background} 120 120 121 121 Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc. 122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), specific times(noon, New Years).122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), time (noon, New Years). 123 123 Many programming languages capture this important software-engineering capability through a mechanism called an \newterm{enumeration}. 124 124 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set. … … 126 126 127 127 Specifically, an enumerated type restricts its values to a fixed set of named constants. 128 While all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc., these values are not named, other than the programming-language supplied constant names. 129 130 Fundamentally, all enumeration systems have an \newterm{enumeration} type with an associated set of \newterm{enumerator} names. 131 An enumeration has three universal attributes, \newterm{position}, \newterm{label}, and \newterm{value}, as shown by this representative enumeration, where position and value can be different. 128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc. 129 However, the values for basic types are not named, other than the programming-language supplied constants. 130 131 132 \section{C-Style Enum} 133 134 The C-Style enumeration has the following syntax and semantics, and is representative of enumerations in many other programming languages (see Section~\ref{s:RelatedWork}). 135 \begin{lstlisting}[label=lst:weekday] 136 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; 137 $\(\uparrow\)$ $\(\uparrow\)$ 138 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}} 139 \end{lstlisting} 140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 141 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constants. 142 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and has no address, it is an rvalue\footnote{ 143 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}. 144 Enumerators without explicitly designated constants are auto-initialized by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 145 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants 0--2, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants 11--13. 146 Hence, there are 3 universal enumeration attributes: \newterm{position}, \newterm{label}, and \newterm{value}: 132 147 \begin{cquote} 133 148 \small\sf\setlength{\tabcolsep}{3pt} 134 149 \begin{tabular}{rccccccccccc} 135 \it\color{red}enumeration & \multicolumn{7}{c}{\it\color{red}enumerators} \\ 136 $\downarrow$\hspace*{25pt} & \multicolumn{7}{c}{$\downarrow$} \\ 137 @enum@ Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday,& Friday, & Saturday, & Sunday \}; \\ 138 \it\color{red}position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 139 \it\color{red}label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 140 \it\color{red}value & 0 & 1 & 2 & 3 & 4 & 5 & 6 150 @enum@ Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday = 10,& Friday, & Saturday, & Sunday \}; \\ 151 \it\color{red}position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 152 \it\color{red}label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 153 \it\color{red}value & 0 & 1 & 2 & {\color{red}10}& 11 & 12 & 13 141 154 \end{tabular} 142 155 \end{cquote} 143 Here, the \newterm{enumeration} @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 144 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constant values. 145 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and an enumerator has no address, it is an \newterm{rvalue}\footnote{ 146 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}. 147 148 149 \section{C-Style Enum} 150 151 The C-Style enumeration has the following syntax and semantics. 152 \begin{lstlisting} 153 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; 154 \end{lstlisting} 155 Enumerators without an explicitly designated constant value are \newterm{auto-initialized} by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 156 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants @0@--@2@, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants @11@--@13@. 157 Initialization may occur in any order. 158 \begin{lstlisting} 159 enum Weekday { Thursday@ = 10@, Friday, Saturday, Sunday, Monday@ = 0@, Tuesday, Wednesday }; 160 \end{lstlisting} 161 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma. 162 \begin{lstlisting} 163 enum Weekday { 164 Thursday = 10, Friday, Saturday, Sunday, 165 Monday = 0, Tuesday, Wednesday@,@ // terminating comma 166 }; 167 \end{lstlisting} 168 This feature allow enumerator lines to be interchanged without moving a comma.\footnote{ 169 A terminating comma appears in other C syntax, e.g., the initializer list.} 170 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type. 156 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 171 157 172 158 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values. 173 In practice, since integral constants are used, whichhave type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables.174 F inally, there is an implicit bidirectional conversion between an enumeration and integral types.159 In practice, since integral constants in C have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables. 160 Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types. 175 161 \begin{lstlisting}[label=lst:enum_scope] 176 162 { 177 enum Weekday { /* as above */ };$\C{// enumerators implicitly projected into local scope}$163 enum Weekday { ... }; $\C{// enumerators implicitly projected into local scope}$ 178 164 Weekday weekday = Monday; $\C{// weekday == 0}$ 179 165 weekday = Friday; $\C{// weekday == 11}$ 180 int i = Sunday ;$\C{// implicit conversion to int, i == 13}$166 int i = Sunday $\C{// implicit conversion to int, i == 13}$ 181 167 weekday = 10000; $\C{// UNDEFINED! implicit conversion to Weekday}$ 182 168 } … … 185 171 The implicit conversion from @int@ to an enumeration type is an unnecessary source of error. 186 172 187 It is common for C programmers to ``believe'' there are 3 equivalent forms of constant enumeration.188 \begin{lstlisting}[label=lst:enum_scope]189 #define Monday 0190 static const int Monday = 0;191 enum { Monday };192 \end{lstlisting}193 For @#define@, the programmer has to play compiler and explicitly manage the enumeration values;194 furthermore, these are independent constants outside of any language type mechanism.195 The same explicit management is true for @const@ declarations, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{196 C allows variable-length array-declarations (VLA), so this case does work, but it fails in \CC, which does not support VLAs, unless it is \lstinline{g++}.} and immediate operands of assembler instructions.197 Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations.198 199 200 173 \section{\CFA-Style Enum} 201 174 … … 203 176 \CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 204 177 205 206 \subsection{Enumerator Name Resolution}207 \label{s:EnumeratorNameResolution}208 209 In C, unscoping of enumerators presents a \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names.210 There is no mechanism in C to resolve these naming conflicts other than renaming of one of the duplicates, which may be impossible.211 212 The \CFA type-system allows extensive overloading, including enumerators.213 Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name.214 Finally, qualification is provided to disambiguate any ambiguous situations.215 \begin{lstlisting}216 enum C1 { First, Second, Third, Fourth };217 enum C2 { @Fourth@, @Third@, @Second@, @First@ };218 C1 p() { return Third; } $\C{// correctly resolved duplicate names}$219 C2 p() { return Fourth; }220 void foo() {221 C1 e1 = First; C2 e2 = First;222 e1 = Second; e2 = Second;223 e1 = p(); e2 = p(); $\C{// correctly resolved function call}$224 int i = @C1.@First + @C2.@First; $\C{// ambiguous without qualification}$225 }226 \end{lstlisting}227 \CFA overloading allows programmers to use the most meaningful names without fear of unresolvable clashes from included files, which are correctable with qualification.228 229 230 \subsection{Enumerator Scoping}231 232 An enumeration can be scoped, so the enumerator constants are not projected into the enclosing scope, using @'!'@.233 \begin{lstlisting}234 enum Weekday @!@ { /* as above */ };235 enum( char * ) Names @!@ { /* as above */ };236 \end{lstlisting}237 Now the enumerators \emph{must} be qualified with the associated enumeration.238 \begin{lstlisting}239 Weekday weekday = @Weekday@.Monday;240 Names names = @Names.@Fred;241 names = @Names.@Jane;242 \end{lstlisting}243 It is possible to toggle back to unscoping using the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}).244 \begin{lstlisting}245 Weekday weekday;246 with ( @Weekday@, @Names@ ) { $\C{// type names}$247 Names names = @Fred@;248 names = @Jane@;249 weekday = Saturday;250 }251 \end{lstlisting}252 As in Section~\ref{s:EnumeratorNameResolution}, opening multiple unscoped enumerations can result in duplicate enumeration names, but \CFA type resolution and falling back to explicit qualification handles name resolution.253 254 178 \subsection{Enumerator Typing} 255 179 256 \CFA extends the enumeration declaration by parameterizing with a type (like a generic type), allowing enumerators to be assigned any values from the declared type. 257 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerator constants. 258 Note, the synonyms @Liz@ and @Beth@ in the last declaration. 259 260 Because enumerators are constants, the enumeration type is implicitly @const@, so all the enumerator types in Figure~\ref{f:EumeratorTyping} are rewritten with @const@. 261 A typed enumeration has an implicit (safe) conversion to its base type. 262 \begin{lstlisting} 263 char currency = Dollar; 264 string fred = Fred; $\C{// implicit conversion from char * to \CFA string type}$ 265 Person student = Beth; 180 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type. 181 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerators. 182 183 Typed enumerates deals with \emph{harmonizing} problem between an enumeration and its companion data. 184 The following example is from the \CFA compiler, written in \CC. 185 \begin{lstlisting} 186 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES }; 187 char * integral_names[NO_OF_ITYPES] = { 188 "char", "signed char", "unsigned char", 189 "signed short int", "unsigned short int", 190 "signed int", "unsigned int", 191 ... 192 }; 193 \end{lstlisting} 194 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit. 195 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment). 196 The typed enumeration largely solves this problem by combining and managing the two data types. 197 \begin{lstlisting} 198 enum( char * ) integral_types { 199 chr = "char", schar = "signed char", uschar = "unsigned char", 200 sshort = "signed short int", ushort = "unsigned short int", 201 sint = "signed int", usint = "unsigned int", 202 ... 203 }; 266 204 \end{lstlisting} 267 205 … … 285 223 enum( @_Complex@ ) Plane { X = 1.5+3.4i, Y = 7+3i, Z = 0+0.5i }; 286 224 // pointer 287 enum( @char *@ ) Names { Fred = "F RED", Mary = "MARY", Jane = "JANE" };225 enum( @char *@ ) Names { Fred = "Fred", Mary = "Mary", Jane = "Jane" }; 288 226 int i, j, k; 289 227 enum( @int *@ ) ptr { I = &i, J = &j, K = &k }; 290 228 enum( @int &@ ) ref { I = i, J = j, K = k }; 291 229 // tuple 292 enum( @[int, int]@ ) { T = [ 1, 2 ] }; $\C{// new \CFA type}$230 enum( @[int, int]@ ) { T = [ 1, 2 ] }; 293 231 // function 294 232 void f() {...} void g() {...} … … 296 234 // aggregate 297 235 struct Person { char * name; int age, height; }; 298 @***@enum( @Person@ ) friends { @Liz@ = { "ELIZABETH", 22, 170 }, @Beth@ = Liz, Jon = { "JONATHAN", 35, 190 } };236 enum( @Person@ ) friends { Liz = { "Elizabeth", 22, 170 }, Beth = Liz, Jon = { "Jonathan", 35, 190 } }; 299 237 \end{lstlisting} 300 238 \caption{Enumerator Typing} … … 302 240 \end{figure} 303 241 304 Typed enumerations deals with the \emph{harmonizing} problem between an enumeration and any companion data.305 The following example is from the \CFA compiler, written in \CC.306 \begin{lstlisting}307 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES };308 char * integral_names[NO_OF_ITYPES] = {309 "char", "signed char", "unsigned char",310 "signed short int", "unsigned short int",311 "signed int", "unsigned int",312 ...313 };314 \end{lstlisting}315 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit.316 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment).317 The typed enumeration largely solves this problem by combining and managing the two data types.318 \begin{lstlisting}319 enum( char * ) integral_types {320 chr = "char", schar = "signed char", uschar = "unsigned char",321 sshort = "signed short int", ushort = "unsigned short int",322 sint = "signed int", usint = "unsigned int",323 ...324 };325 \end{lstlisting}326 Note, the enumeration type can be a structure (see @Person@ in Figure~\ref{f:EumeratorTyping}), so it is possible to have the equivalent of multiple arrays of companion data using an array of structures.327 328 329 242 \subsection{Pure Enumerators} 330 243 331 An empty enumerator type, @enum()@, implies the enumerators are pure symbols without values but set properties;244 An empty type, @enum()@, implies the enumerators are pure symbols without values; 332 245 hence, there is no default conversion to @int@. 333 246 334 247 \begin{lstlisting} 335 248 enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 336 @***@Mode iomode = O_RDONLY; 337 bool b = iomode == O_RDONLY || iomode < O_APPEND; 249 Mode iomode = O_RDONLY; 338 250 int i = iomode; $\C{\color{red}// disallowed}$ 251 sout | O_TRUNC; $\C{\color{red}// disallowed}$ 339 252 \end{lstlisting} 340 253 341 254 \subsection{Enumerator Subset} 342 255 343 If follows from enumerator typing that the enumerator type can be another enumerator. 344 \begin{lstlisting} 345 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 346 enum( @Currency@ ) Europe { Euro = Currency.Euro, Pound = Currency.Pound }; // intersection 256 If follows from enumerator typing that the type of the enumerators can be another enumerator. 257 \begin{lstlisting} 347 258 enum( char ) Letter { A = 'A', B = 'B', C = 'C', ..., Z = 'Z' }; 348 enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // intersection 349 \end{lstlisting} 350 Subset enumerations may have more or less enumerators than their typed enumeration, but the enumerator values must be from the typed enumeration. 351 For example, @Greek@ enumerators are a subset of type @Letter@ and are type compatible with enumeration @Letter@, but @Letter@ enumerators are not type compatible with enumeration @Greek@. 352 \begin{lstlisting} 259 enum( Letter ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection 353 260 Letter letter = A; 354 @***@Greak greek = Beta;355 letter = Beta; $\C{// allowed, letter == B}$261 Greak greek = Alph; 262 letter = Alph; $\C{// allowed}$ 356 263 greek = A; $\C{\color{red}// disallowed}$ 357 264 \end{lstlisting} 358 265 Enumeration @Greek@ may have more or less enumerators than @Letter@, but the enumerator values must be from @Letter@. 266 Therefore, @Greek@ enumerators are a subset of type @Letter@ and are type compatible with enumeration @Letter@, but @Letter@ enumerators are not type compatible with enumeration @Greek@. 359 267 360 268 \subsection{Enumeration Inheritance} 361 269 362 \CFA Plan-9 inheritance may be used with enumerations, where Plan-9 inheritance is containment inheritance with implicit unscoping (like a nested unnamed @struct@/@union@ in C). 363 \begin{lstlisting} 364 enum( char * ) Names { /* as above */ }; 365 enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" }; 366 @***@enum /* inferred */ Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" }; 367 \end{lstlisting} 368 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@. 270 \CFA Plan-9 inheritance may be used with enumerations. 271 \begin{lstlisting} 272 enum( char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" }; 273 enum /* inferred */ Name3 { @inline Name2@, Sue = "Sue", Tom = "Tom" }; 274 \end{lstlisting} 275 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Name@ by containment, and a @Name@ enumeration is a subtype of enumeration @Name2@. 369 276 Note, enumerators must be unique in inheritance but enumerator values may be repeated. 370 277 371 278 The enumeration type for the inheriting type must be the same as the inherited type; 372 279 hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@. 373 % When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 374 Specifically, the inheritance relationship for @Names@ is: 375 \begin{lstlisting} 376 Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\(\subset\)$ const char * $\C{// enum type of Names}$ 280 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 281 282 Specifically, the inheritance relationship for Names is: 283 \begin{lstlisting} 284 Name $\(\subset\)$ Name2 $\(\subset\)$ Name3 $\(\subset\)$ const char * // enum type of Name 377 285 \end{lstlisting} 378 286 For the given function prototypes, the following calls are valid. … … 380 288 \begin{tabular}{ll} 381 289 \begin{lstlisting} 382 void f( Name s);383 void g( Name s2 );384 void h( Name s3 );290 void f( Name ); 291 void g( Name2 ); 292 void h( Name3 ); 385 293 void j( const char * ); 386 294 \end{lstlisting} … … 390 298 g( Fred ); g( Jill ); 391 299 h( Fred ); h( Jill ); h( Sue ); 392 j( Fred ); j( Jill ); j( Sue ); j( "W ILL" );300 j( Fred ); j( Jill ); j( Sue ); j( "Will" ); 393 301 \end{lstlisting} 394 302 \end{tabular} 395 303 \end{cquote} 396 Note, the validity of calls is the same for call-by-reference as for call-by-value, and @const@ restrictions are the same as for other types. 397 304 Note, the validity of calls is the same for call-by-reference as for call-by-value, and const restrictions are the same as for other types. 305 306 \subsection{Enumerator Scoping} 307 308 A \CFA-enum can be scoped, meaning the enumerator constants are not projected into the enclosing scope. 309 \begin{lstlisting} 310 enum Weekday @!@ { /* as above */ }; 311 enum Colour( char * ) @!@ { /* as above */ }; 312 \end{lstlisting} 313 where the @'!'@ implies the enumerators are \emph{not} projected. 314 The enumerators of a scoped enumeration are accessed using qualifications, like the fields of an aggregate. 315 % The syntax of $qualified\_expression$ for \CFA-enum is the following: 316 % $$<qualified\_expression> := <enum\_type>.<enumerator>$$ 317 \begin{lstlisting} 318 Weekday weekday = @Weekday.Monday@; $\C{// qualification}$ 319 Colour colour = @Colour.@Red; 320 colour = @Colour.@Blue; 321 \end{lstlisting} 398 322 399 323 \subsection{Enumeration Pseudo-functions} 400 324 401 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@ , @offsetof@, @typeof@.325 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. 402 326 Often a call to a pseudo-function is substituted with information extracted from the symbol table at compilation time, like storage size or alignment associated with the underlying architecture.. 403 327 328 \subsubsection{Enumerator Attributes} 404 329 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 405 330 \begin{lstlisting} 406 @***@int jane_pos = @position@( Names.Jane ); $\C{// 2}$ 407 @***@char * jane_value = @value@( Names.Jane ); $\C{// "JANE"}$ 408 @***@char * jane_label = @label@( Names.Jane ); $\C{// "Jane"}$ 409 sout | @label@( Names.Jane ) | @value@( Names.Jane ); 410 \end{lstlisting} 411 Note the ability to print both enumerator label and value. 412 413 414 \subsection{Enumerator Position or Value} 415 416 Enumerators can be used in multiple contexts. 417 In most programming languages, an enumerator is implicitly converted to its value (like a typed macro substitution). 418 However, enumerator synonyms and typed enumerations make this implicit conversion to value incorrect in some contexts. 419 In these contexts, a programmer's initition assumes an implicit conversion to postion. 420 421 For example, an intuitive use of enumerations is with the \CFA @switch@/@choose@ statement, where @choose@ performs an implict @break@ rather than a fall-through at the end of a @case@ clause. 422 \begin{cquote} 423 \begin{lstlisting} 424 enum Count { First, Second, Third, Fourth }; 425 Count e; 426 \end{lstlisting} 427 \begin{tabular}{ll} 428 \begin{lstlisting} 429 430 choose( e ) { 431 case @First@: ...; 432 case @Second@: ...; 433 case @Third@: ...; 434 case @Fourth@: ...; 435 } 436 \end{lstlisting} 437 & 438 \begin{lstlisting} 439 // rewrite 440 choose( @value@( e ) ) { 441 case @value@( First ): ...; 442 case @value@( Second ): ...; 443 case @value@( Third ): ...; 444 case @value@( Fourth ): ...; 445 } 446 \end{lstlisting} 447 \end{tabular} 448 \end{cquote} 449 Here, the intuitive code on the left is implicitly transformed into the statndard implementation on the right, using the value of the enumeration variable and enumerators. 450 However, this implementation is fragile, e.g., if the enumeration is changed to: 451 \begin{lstlisting} 452 enum Count { First, Second, Third @= First@, Fourth }; 453 \end{lstlisting} 454 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicase @case@ clauses. 455 To better match with programmer intuition, \CFA toggles between value and position semantics depneding on the language context. 456 For conditional clauses and switch statments, \CFA uses the robust position implementation. 457 \begin{lstlisting} 458 choose( @position@( e ) ) { 459 case @position@( First ): ...; 460 case @position@( Second ): ...; 461 case @position@( Third ): ...; 462 case @position@( Fourth ): ...; 463 } 464 \end{lstlisting} 465 466 \begin{lstlisting} 467 Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 331 int green_pos = @position@( Colour.Green ); $\C{// 1}$ 332 char * green_value = @value@( Colour.Green ); $\C{// "G"}$ 333 char * green_label = @label@( Colour.Green ); $\C{// "Green"}$ 334 \end{lstlisting} 335 336 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter. 337 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek. 338 339 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. 340 % The label can be retrieved by calling the function @label( <enum_instance> )@. 341 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum. 342 343 \subsubsection{\lstinline{enumerate()}} 344 345 \begin{lstlisting}[label=lst:c_switch] 346 enum(int) C_ENUM { First, Second, Third = First, Fourth }; 347 int v( C_ENUM e ) { 348 switch( e ) { 349 case First: return 0; break; 350 case Second: return 1; break; 351 // case Third: return 2; break; 352 // case Fourth: return 3; break; 353 }; 354 }; 355 \end{lstlisting} 356 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. 357 Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. 358 Case @First@ and @Third@, or @Second@ and @Fourth@, has duplicate case values. 359 360 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 361 \begin{lstlisting}[label=lst:c_switch_enumerate] 362 enum(double) C_ENUM { First, Second, Third = First, Fourth }; 363 C_ENUM variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 364 int v(C_ENUM e) { 365 switch( enumeratate( e ) ) { 366 case First: return e; break; 367 case Second: return value( e ); break; 368 case Third: return label( e ); break; 369 case Fourth: return position( e ); break; 370 }; 371 }; 468 372 p(variable_a); // 0 469 373 p(variable_b); // 1 … … 1111 1015 If the @aggregation_name@ is identified as a \CFA enumeration, the compiler checks if @field@ presents in the declared \CFA enumeration. 1112 1016 1017 \subsection{\lstinline{with} Clause/Statement} 1018 1019 Instead of qualifying an enumeration expression every time, the @with@ can be used to expose enumerators to the current scope, making them directly accessible. 1020 \begin{lstlisting}[label=lst:declaration] 1021 enum Color( char * ) { Red="R", Green="G", Blue="B" }; 1022 enum Animal( int ) { Cat=10, Dog=20 }; 1023 with ( Color, Animal ) { 1024 char * red_string = Red; // value( Color.Red ) 1025 int cat = Cat; // value( Animal.Cat ) 1026 } 1027 \end{lstlisting} 1028 The \lstinline{with} might introduce ambiguity to a scope. Consider the example: 1029 \begin{lstlisting}[label=lst:declaration] 1030 enum Color( char * ) { Red="R", Green="G", Blue="B" }; 1031 enum RGB( int ) { Red=0, Green=1, Blue=2 }; 1032 with ( Color, RGB ) { 1033 // int red = Red; 1034 } 1035 \end{lstlisting} 1036 \CFA will not try to resolve the expression with ambiguity. It would report an error. In this case, it is necessary to qualify @Red@ even inside of the \lstinline{with} clause. 1037 1113 1038 \subsection{Instance Declaration} 1114 1039 … … 1293 1218 1294 1219 \subsection{\CC} 1295 \label{s:C++RelatedWork} 1296 1297 \CC is backwards compatible with C, so it inherited C's enumerations. 1298 However, the following non-backwards compatible changes have been made. 1299 \begin{quote} 1300 7.2 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type. 1301 In C, objects of enumeration type can be assigned values of any integral type. \\ 1302 Example: 1303 \begin{lstlisting} 1304 enum color { red, blue, green }; 1305 color c = 1; $\C{// valid C, invalid C++}$ 1306 \end{lstlisting} 1307 \textbf{Rationale}: The type-safe nature of C++. \\ 1308 \textbf{Effect on original feature}: Deletion of semantically well-defined feature. \\ 1309 \textbf{Difficulty of converting}: Syntactic transformation. (The type error produced by the assignment can be automatically corrected by applying an explicit cast.) \\ 1310 \textbf{How widely used}: Common. 1311 \end{quote} 1312 \begin{quote} 1313 7.2 Change: In \CC, the type of an enumerator is its enumeration. 1314 In C, the type of an enumerator is @int@. \\ 1315 Example: 1316 \begin{lstlisting} 1317 enum e { A }; 1318 sizeof(A) == sizeof(int) $\C{// in C}$ 1319 sizeof(A) == sizeof(e) $\C{// in C++}$ 1320 /* and sizeof(int) is not necessary equal to sizeof(e) */ 1321 \end{lstlisting} 1322 \textbf{Rationale}: In C++, an enumeration is a distinct type. \\ 1323 \textbf{Effect on original feature}: Change to semantics of well-defined feature. \\ 1324 \textbf{Difficulty of converting}: Semantic transformation. \\ 1325 \textbf{How widely used}: Seldom. The only time this affects existing C code is when the size of an enumerator is taken. 1326 Taking the size of an enumerator is not a common C coding practice. 1327 \end{quote} 1328 Hence, the values in a \CC enumeration can only be its enumerators (without a cast). 1329 While the storage size of an enumerator is up to the compiler, there is still an implicit cast to @int@. 1330 \begin{lstlisting} 1331 enum E { A, B, C }; 1332 E e = A; 1333 int i = A; i = e; $\C{// implicit casts to int}$ 1334 \end{lstlisting} 1335 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification. 1220 1221 \CC is backwards compatible with C, so it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration; 1222 hence, the values in a \CC enumeration can only be its enumerators (without a cast). 1223 There is no mechanism to iterate through an enumeration. 1224 1225 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification, e.g., @Weekday::Monday@. 1226 \CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration. 1227 1228 For both unscoped and scoped enumerations, the underlying type is an implementation-defined integral type large enough to hold all enumerated values; it does not have to be the smallest possible type. 1229 In \CC{11}, the underlying integral type can be explicitly specified: 1336 1230 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 1337 enum class E { A, B, C }; 1338 E e = @E::@A; $\C{// qualified enumerator}$ 1339 e = B; $\C{// B not in scope}$ 1340 \end{lstlisting} 1341 \CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration. 1342 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 1343 enum class E { A, B, C }; 1344 @using enum E;@ 1345 E e = A; $\C{// direct access}$ 1346 e = B; $\C{// direct access}$ 1347 \end{lstlisting} 1348 \CC{11} added the ability to explicitly declare the underlying integral type for \lstinline[language=c++]{enum class}. 1349 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 1350 enum class RGB @: long@ { Red, Green, Blue }; 1351 enum class rgb @: char@ { Red = 'r', Green = 'g', Blue = 'b' }; 1352 enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 }; 1353 \end{lstlisting} 1354 There is no implicit conversion from the \lstinline[language=c++]{enum class} type and to its type. 1355 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 1356 rgb crgb = rgb::Red; 1357 char ch = rgb::Red; ch = crgb; $\C{// disallowed}$ 1358 \end{lstlisting} 1359 Finally, there is no mechanism to iterate through an enumeration nor use the enumeration type to declare an array dimension. 1360 1231 enum class RGB : @long@ { Red, Green, Blue }; 1232 enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' }; 1233 enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 }; 1234 RGB colour1 = @RGB::@Red; 1235 rgb colour2 = @rgb::@Red; 1236 srgb colour3 = @srgb::@Red; 1237 \end{lstlisting} 1361 1238 1362 1239 \subsection{Go}
Note:
See TracChangeset
for help on using the changeset viewer.