| 1 | \chapter{Background}
|
|---|
| 2 |
|
|---|
| 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.
|
|---|
| 5 |
|
|---|
| 6 | It is common for C programmers to ``believe'' there are three equivalent forms of named constants.
|
|---|
| 7 | \begin{clang}
|
|---|
| 8 | #define Mon 0
|
|---|
| 9 | static const int Mon = 0;
|
|---|
| 10 | enum { Mon };
|
|---|
| 11 | \end{clang}
|
|---|
| 12 | \begin{enumerate}[leftmargin=*]
|
|---|
| 13 | \item
|
|---|
| 14 | For @#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.
|
|---|
| 16 | \item
|
|---|
| 17 | The 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{
|
|---|
| 18 | 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++}.} immediate operands of assembler instructions, and occupy storage.
|
|---|
| 19 | \begin{clang}
|
|---|
| 20 | $\$$ nm test.o
|
|---|
| 21 | 0000000000000018 r Mon
|
|---|
| 22 | \end{clang}
|
|---|
| 23 | \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.
|
|---|
| 25 | \end{enumerate}
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 | \section{C \lstinline{const}}
|
|---|
| 29 |
|
|---|
| 30 | As noted, C has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization.
|
|---|
| 31 | \begin{clang}
|
|---|
| 32 | static const int one = 0 + 1; $\C{// static intialization}$
|
|---|
| 33 | static const void * NIL = NULL;
|
|---|
| 34 | static const double PI = 3.14159;
|
|---|
| 35 | static const char Plus = '+';
|
|---|
| 36 | static const char * Fred = "Fred";
|
|---|
| 37 | static const int Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1,
|
|---|
| 38 | Sat = Fri + 1, Sun = Sat + 1;
|
|---|
| 39 | void foo() {
|
|---|
| 40 | const int r = random(); $\C{// dynamic intialization}$
|
|---|
| 41 | int sa[Sun]; $\C{// VLA, local scope only}$
|
|---|
| 42 | }
|
|---|
| 43 | \end{clang}
|
|---|
| 44 | Statically 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.
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 | \section{C Enumeration}
|
|---|
| 49 | \label{s:CEnumeration}
|
|---|
| 50 |
|
|---|
| 51 | The C enumeration has the following syntax~\cite[\S~6.7.2.2]{C11}.
|
|---|
| 52 | \begin{clang}[identifierstyle=\linespread{0.9}\it]
|
|---|
| 53 | $\it enum$-specifier:
|
|---|
| 54 | enum identifier$\(_{opt}\)$ { enumerator-list }
|
|---|
| 55 | enum identifier$\(_{opt}\)$ { enumerator-list , }
|
|---|
| 56 | enum identifier
|
|---|
| 57 | enumerator-list:
|
|---|
| 58 | enumerator
|
|---|
| 59 | enumerator-list , enumerator
|
|---|
| 60 | enumerator:
|
|---|
| 61 | enumeration-constant
|
|---|
| 62 | enumeration-constant = constant-expression
|
|---|
| 63 | \end{clang}
|
|---|
| 64 | The 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.
|
|---|
| 66 |
|
|---|
| 67 | An unnamed enumeration is used to provide secondary renaming, like a @const@ declaration in other languages.
|
|---|
| 68 | \begin{clang}
|
|---|
| 69 | enum { Size = 20, Pi = 3.14159 }; // unnamed enumeration $\(\Rightarrow\)$ no ordering
|
|---|
| 70 | \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.
|
|---|
| 72 |
|
|---|
| 73 | A \emph{named} enumeration type is an actual enumeration.
|
|---|
| 74 | \begin{clang}
|
|---|
| 75 | enum Weekday { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun, };
|
|---|
| 76 | \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@.
|
|---|
| 78 | For 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.
|
|---|
| 80 | \begin{clang}
|
|---|
| 81 | enum Weekday { Thu@ = 10@, Fri, Sat, Sun, Mon@ = 0@, Tue, Wed };
|
|---|
| 82 | \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.
|
|---|
| 84 | \begin{clang}
|
|---|
| 85 | enum Weekday {
|
|---|
| 86 | Thu = 10, Fri, Sat, Sun,
|
|---|
| 87 | Mon = 0, Tue, Wed@,@ // terminating comma
|
|---|
| 88 | };
|
|---|
| 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.
|
|---|
| 93 |
|
|---|
| 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.
|
|---|