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. |
---|