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