Ignore:
Timestamp:
Apr 28, 2024, 3:49:00 PM (7 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
5c27b6a, caaf424
Parents:
e78966e
Message:

more proofreading on enumeration chapters

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/jiada_liang_MMath/background.tex

    re78966e rf632117  
    11\chapter{Background}
    22
    3 \CFA is a backwards-compatible extension of the C programming language.
    4 Therefore, it must support C-style enumerations and any enumeration extensions must be intuitive to C programmers both in syntax and semantics.
     3\CFA is a backwards-compatible extension of the C programming language, therefore, it must support C-style enumerations.
     4The following covers C enumerations.
    55
    6 It is common for C programmers to ``believe'' there are three equivalent forms of named constants.
     6As discussed in \VRef{s:Aliasing}, it is common for C programmers to ``believe'' there are three equivalent forms of named constants.
    77\begin{clang}
    88#define Mon 0
     
    1313\item
    1414For @#define@, the programmer has to explicitly manage the constant name and value.
    15 Furthermore, these C preprocessor macro names are outside of the C type-system, and hence cannot be overloaded, and can incorrectly change random text in a program.
     15Furthermore, these C preprocessor macro names are outside of the C type-system and can incorrectly change random text in a program.
    1616\item
    1717The same explicit management is true for the @const@ declaration, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{
     
    2222\end{clang}
    2323\item
    24 Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations.
     24Only the @enum@ form is managed by the compiler, is part of the language type-system, works in all C constant-expression locations, and might not occupy storage..
    2525\end{enumerate}
    2626
    2727
    2828\section{C \lstinline{const}}
     29\label{s:Cconst}
    2930
    30 As noted, C has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization.
     31C can simulate the aliasing @const@ declarations \see{\VRef{s:Aliasing}}, with static and dynamic initialization.
    3132\begin{clang}
    32 static const int one = 0 + 1;                   $\C{// static intialization}$
     33static const int one = 0 + 1;                   $\C{// static initialization}$
    3334static const void * NIL = NULL;
    3435static const double PI = 3.14159;
     
    3839                                        Sat = Fri + 1, Sun = Sat + 1;
    3940void foo() {
    40         const int r = random();                         $\C{// dynamic intialization}$
    41         int sa[Sun];                                            $\C{// VLA, local scope only}$
     41        const int r = random() % 100;           $\C{// dynamic intialization}$
     42        int va[r];                                                      $\C{// VLA, auto scope only}$
    4243}
    4344\end{clang}
    4445Statically initialized identifiers may appear in any constant-expression context, \eg @case@.
    45 Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays.
     46Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays on the stack.
     47Again, this form of aliasing to primary constant is not an enumeration.
    4648
    4749
     
    6365\end{clang}
    6466The terms \emph{enumeration} and \emph{enumerator} used in this work \see{\VRef{s:Terminology}} come from the grammar.
    65 The C enumeration semantics is discussed using examples.
     67The C enumeration semantics are discussed using examples.
    6668
    67 An unnamed enumeration is used to provide secondary renaming, like a @const@ declaration in other languages.
     69
     70\subsection{Type Name}
     71\label{s:TypeName}
     72
     73An \emph{unnamed} enumeration is used to provide aliasing \see{\VRef{s:Aliasing}} exactly like a @const@ declaration in other languages.
     74However, it is restricted to integral values.
    6875\begin{clang}
    69 enum { Size = 20, Pi = 3.14159 };   // unnamed enumeration $\(\Rightarrow\)$ no ordering
     76enum { Size = 20, Max = 10, MaxPlus10 = Max + 10, Max10Plus1, Fred = -7 };
    7077\end{clang}
    71 This declaration form is not an enumeration even though it is declared using an @enum@ because it has none of the following enumeration properties.
     78Here, the aliased constants are: 20, 10, 20, 21, and -7.
     79Direct initialization is by a compile-time expression generating a constant value.
     80An enumerator without initialization is \Newterm{auto-initialized}: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.
     81Because multiple independent enumerators can be combined, enumerators with the same values can occur.
     82The enumerators are rvalues, so assignment is disallowed.
     83Finally, enumerators are \Newterm{unscoped}, \ie enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type.
     84For unnamed enumeration this semantic is required because there is no type name for scoped qualification.
    7285
    73 A \emph{named} enumeration type is an actual enumeration.
     86As noted, this kind of aliasing declaration is not an enumeration, even though it is declared using an @enum@ in C.
     87While the semantics is misleading, this enumeration form matches with aggregate types:
     88\begin{cfa}
     89typedef struct /* unnamed */  { ... } S;
     90struct /* unnamed */  { ... } x, y, z;                  $\C{// questionable}$
     91struct S {
     92        union /* unnamed */ {                                           $\C{// unscoped fields}$
     93                int i;  double d ;  char ch;
     94        };
     95};
     96\end{cfa}
     97Hence, C programmers would expect this enumeration form to exist in harmony with the aggregate form.
     98
     99A \emph{named} enumeration is an enumeration:
    74100\begin{clang}
    75 enum Weekday { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun, };
     101enum @Week@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun };
    76102\end{clang}
    77 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@.
     103and adopts the same semantics with respect to direct and auto intialization.
    78104For example, @Mon@ to @Wed@ are implicitly assigned with constants @0@--@2@, @Thu@ is explicitly set to constant @10@, and @Fri@ to @Sun@ are implicitly assigned with constants @11@--@13@.
    79 Initialization may occur in any order.
     105As well, initialization may occur in any order.
    80106\begin{clang}
    81 enum Weekday { Thu@ = 10@, Fri, Sat, Sun, Mon@ = 0@, Tue, Wed };
     107enum Week {
     108        Thu@ = 10@, Fri, Sat, Sun,
     109        Mon@ = 0@, Tue, Wed@,@ }; // terminating comma
    82110\end{clang}
    83 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.
     111Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.\footnote{
     112A terminating comma appears in other C syntax, \eg the initializer list.}
     113This feature allow enumerator lines to be interchanged without moving a comma.
     114Named enumerators are also unscoped.
     115
     116
     117\subsection{Implementation}
     118
     119In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values.
     120In practice, C uses @int@ as the underlying type for enumeration variables, because of the restriction to integral constants, which have type @int@ (unless qualified with a size suffix).
     121
     122
     123\subsection{Usage}
     124\label{s:Usage}
     125
     126C proves an implicit \emph{bidirectional} conversion between an enumeration and its integral type.
    84127\begin{clang}
    85 enum Weekday {
    86         Thu = 10, Fri, Sat, Sun,
    87         Mon = 0, Tue, Wed@,@ // terminating comma
     128enum Week week = Mon;                           $\C{// week == 0}$
     129week = Fri;                                                     $\C{// week == 11}$
     130int i = Sun;                                            $\C{// implicit conversion to int, i == 13}$
     131@week = 10000;@                                         $\C{// UNDEFINED! implicit conversion to Week}$
     132\end{clang}
     133While converting an enumerator to underlying type is useful, the implicit conversion from the base type to an enumeration type is a common source of error.
     134
     135Enumerators can appear in @switch@ and looping statements.
     136\begin{cfa}
     137enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
     138switch ( week ) {
     139        case Mon: case Tue: case Wed: case Thu: case Fri:
     140                printf( "weekday\n" );
     141        case Sat: case Sun:
     142                printf( "weekend\n" );
     143}
     144for ( enum Week day = Mon; day <= Sun; day += 1 ) {
     145        printf( "day %d\n", day ); // 0-6
     146}
     147\end{cfa}
     148For iterating, the enumerator values \emph{must} have a consecutive ordering with a fixed step between values.
     149Note, it is the bidirectional conversion that allows incrementing @day@: @day@ is converted to @int@, integer @1@ is added, and the result is converted back to @Week@ for the assignment to @day@.
     150For safety, \CC does not support the bidirectional conversion, and hence, an unsafe cast is necessary to increment @day@: @day = (Week)(day + 1)@.
     151
     152There is a C idiom to automatically know the number of enumerators in an enumeration.
     153\begin{cfa}
     154enum E { A, B, C, D, @N@ };  // N == 4
     155for ( enum E e = A; e < @N@; e += 1 ) ...
     156\end{cfa}
     157Here, the auto-incrementing counts the number of enumerators and puts the total into the last enumerator @N@.
     158@N@ is often used as the dimension for an array assocated with the enumeration.
     159\begin{cfa}
     160E array[@N@];
     161for ( enum E e = A; e < N; e += 1 ) {
     162        array[e] = e;
     163}
     164\end{cfa}
     165However, for typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails.
     166
     167This idiom leads to another C idiom using an enumeration with matching companion information.
     168For example, an enumeration is linked with a companion array of printable strings.
     169\begin{cfa}
     170enum Integral_Type { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES };
     171char * Integral_Name[@NO_OF_ITYPES@] = {
     172        "char", "signed char", "unsigned char",
     173        "signed short int", "unsigned short int",
     174        "signed int", "unsigned int", ...
    88175};
    89 \end{clang}
    90 This feature allow enumerator lines to be interchanged without moving a comma.\footnote{
    91 A terminating comma appears in other C syntax, \eg the initializer list.}
    92 Finally, C enumerators are \Newterm{unscoped}, \ie enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type.
     176enum Integral_Type integral_type = ...
     177printf( "%s\n", Integral_Name[@integral_type@] ); // human readable type name
     178\end{cfa}
     179However, the companion idiom results in the \emph{harmonizing} problem because an update to the enumeration @Integral_Type@ often requires a corresponding update to the companion array \snake{Integral_Name}.
     180The need to harmonize is at best indicated by a comment before the enumeration.
     181This issue is exacerbated if enumeration and companion array are in different translation units.
    93182
    94 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values.
    95 In practice, since integral constants are used, which have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables.
    96 Finally, there is an implicit bidirectional conversion between an enumeration and its integral type.
    97 \begin{clang}
    98 {
    99         enum Weekday { /* as above */ };        $\C{// enumerators implicitly projected into local scope}$
    100         Weekday weekday = Mon;                          $\C{// weekday == 0}$
    101         weekday = Fri;                                          $\C{// weekday == 11}$
    102         int i = Sun;                                            $\C{// implicit conversion to int, i == 13}$
    103         weekday = 10000;                                        $\C{// UNDEFINED! implicit conversion to Weekday}$
    104 }
    105 int j = Wed;                                                    $\C{// ERROR! Wed is not declared in this scope}$
    106 \end{clang}
    107 The implicit conversion from @int@ to an enumeration type is an unnecessary source of error.
     183\bigskip
     184While C provides a true enumeration, it is restricted, has unsafe semantics, and does provide enumeration features in other programming languages.
Note: See TracChangeset for help on using the changeset viewer.