\chapter{Background} \lstnewenvironment{clang}[1][]{\lstset{language=[ANSI]C,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{} \CFA is a backwards-compatible extension of the C programming language. Therefore, it must support C-style enumerations and any enumeration extensions must be intuitive to C programmers both in syntax and semantics. It is common for C programmers to ``believe'' there are three equivalent forms of named constants. \begin{clang} #define Mon 0 static const int Mon = 0; enum { Mon }; \end{clang} \begin{enumerate}[leftmargin=*] \item For @#define@, the programmer has to explicitly manage the constant name and value. 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. \item 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{ 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. \begin{clang} $\$$ nm test.o 0000000000000018 r Mon \end{clang} \item Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations. \end{enumerate} \section{C \lstinline{const}} As noted, C has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization. \begin{clang} static const int one = 0 + 1; $\C{// static intialization}$ static const void * NIL = NULL; static const double PI = 3.14159; static const char Plus = '+'; static const char * Fred = "Fred"; static const int Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1, Sat = Fri + 1, Sun = Sat + 1; void foo() { const int r = random(); $\C{// dynamic intialization}$ int sa[Sun]; $\C{// VLA, local scope only}$ } \end{clang} Statically initialized identifiers may appear in any constant-expression context, \eg @case@. Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays. \section{C Enumeration} The C enumeration has the following syntax and semantics. \begin{clang} enum Weekday { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun, }; \end{clang} 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@. 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@. Initialization may occur in any order. \begin{clang} enum Weekday { Thu@ = 10@, Fri, Sat, Sun, Mon@ = 0@, Tue, Wed }; \end{clang} Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma. \begin{clang} enum Weekday { Thu = 10, Fri, Sat, Sun, Mon = 0, Tue, Wed@,@ // terminating comma }; \end{clang} This feature allow enumerator lines to be interchanged without moving a comma.\footnote{ A terminating comma appears in other C syntax, \eg the initializer list.} Finally, C enumerators are \Newterm{unscoped}, \ie enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type. In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values. 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. Finally, there is an implicit bidirectional conversion between an enumeration and its integral type. \begin{clang} { enum Weekday { /* as above */ }; $\C{// enumerators implicitly projected into local scope}$ Weekday weekday = Mon; $\C{// weekday == 0}$ weekday = Fri; $\C{// weekday == 11}$ int i = Sun; $\C{// implicit conversion to int, i == 13}$ weekday = 10000; $\C{// UNDEFINED! implicit conversion to Weekday}$ } int j = Wed; $\C{// ERROR! Wed is not declared in this scope}$ \end{clang} The implicit conversion from @int@ to an enumeration type is an unnecessary source of error.