\chapter{C Enumeration in \CFA} \CFA supports legacy C enumeration using the same syntax for backwards compatibility. A C-style enumeration in \CFA is called a \newterm{C Enum}. The semantics of the C Enum is mostly consistent with C with some restrictions. The following sections detail all of my new contributions to enumerations in C. \section{Enumerator Visibility} \label{s:EnumeratorVisibility} In C, unscoped enumerators present a \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names. \begin{cfa} enum E1 { First, Second, Third, Fourth }; enum E2 { @Fourth@, @Third@, @Second@, @First@ }; $\C{// same enumerator names}$ \end{cfa} There is no mechanism in C to resolve these naming conflicts other than renaming one of the duplicates, which may be impossible if the conflict comes from system include files. The \CFA type-system allows extensive overloading, including enumerators. Hence, most ambiguities among C enumerators are implicitly resolved by the \CFA type system, possibly without any programmer knowledge of the conflict. In addition, C Enum qualification is added, exactly like aggregate field-qualification, to disambiguate. \VRef[Figure]{f:EnumeratorVisibility} shows how resolution, qualification, and casting are used to disambiguate situations for enumerations @E1@ and @E2@. \begin{figure} \begin{cfa} E1 f() { return Third; } $\C{// overload functions with different return types}$ E2 f() { return Fourth; } void g( E1 e ); void h( E2 e ); void foo() { $\C{// different resolutions and dealing with ambiguities}$ E1 e1 = First; E2 e2 = First; $\C{// initialization}$ e1 = Second; e2 = Second; $\C{// assignment}$ e1 = f(); e2 = f(); $\C{// function return}$ g( First ); h( First ); $\C{// function argument}$ int i = @E1.@First + @E2.@First; $\C{// disambiguate with qualification}$ int j = @(E1)@First + @(E2)@First; $\C{// disambiguate with cast}$ } \end{cfa} \caption{Enumerator Visibility and Disambiguating} \label{f:EnumeratorVisibility} \end{figure} \section{Enumerator Scoping} A C Enum can be scoped, using @'!'@, so the enumerator constants are not projected into the enclosing scope. \begin{cfa} enum Week @!@ { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; enum RGB @!@ { Red, Green, Blue }; \end{cfa} Now the enumerators \emph{must} be qualified with the associated enumeration type. \begin{cfa} Week week = @Week.@Mon; week = @Week.@Sat; RGB rgb = @RGB.@Red; rgb = @RGB.@Blue; \end{cfa} % with feature unimplemented It is possible to toggle back to unscoped using the \CFA @with@ auto-qualification clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}). \begin{cfa} with ( @Week@, @RGB@ ) { $\C{// type names}$ week = @Sun@; $\C{// no qualification}$ rgb = @Green@; } \end{cfa} As in Section~\ref{s:EnumeratorVisibility}, opening multiple scoped enumerations in a @with@ can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handle this localized scenario. A partially implemented extension to enumerator scoping is providing a combination of scoped and unscoped enumerators, using individual denotations, where @'^'@ means unscoped. \begin{cfa} enum E1 { @!@A, @^@B, C }; enum E2 @!@ { @!@A, @^@B, C }; \end{cfa} For @E1@, @A@ is scoped; @B@ and @C@ are unscoped. For @E2@, @A@ and @C@ are scoped; @B@ is unscoped. Finding a use case is important to justify completing this extension. \section{Type Safety} As in Section~\ref{s:Usage}, C's implicit bidirectional conversion between enumeration and integral type raises a safety concern. In \CFA, the conversion is changed to unidirectional: an enumeration can be implicitly converted into an integral type, with an associated @safe@ conversion cost. But an integral type cannot be implicitly converted into a C enumeration because the conversion cost is set to @infinity@. \begin{cfa} enum Bird { Penguin, Robin, Eagle }; enum Fish { Shark, Salmon, Whale }; int i = Robin; $\C{// allow, implicitly converts to 1}$ enum Bird @bird = 1;@ $\C{// disallow }$ enum Bird @bird = Shark;@ $\C{// disallow }$ \end{cfa} It is now up to the programmer to insert an explicit cast to force the assignment. \begin{cfa} enum Bird bird = @(Bird)@1; enum Bird bird = @(Bird)@Shark \end{cfa} Note, \CC has the same safe restriction~\cite[C.1.5.7.2]{C++} and provides the same workaround cast. \begin{description}[parsep=0pt] \item[Change:] \CC objects of enumeration type can only be assigned values of the same enumeration type. In C, objects of enumeration type can be assigned values of any integral type. Example: \begin{cfa} enum color { red, blue, green }; color c = 1; $\C{// valid C, invalid \CC}$ \end{cfa} \item[Rationale:] The type-safe nature of \CC. \item[Effect on original feature:] Deletion of semantically well-defined feature. \item[Difficulty of converting:] Syntactic transformation. (The type error produced by the assignment can be automatically corrected by applying an explicit cast.) \item[How widely used:] Common. \end{description} \begin{comment} \begin{description}[parsep=0pt] \item[Change:] In \CC, the type of an enumerator is its enumeration. In C, the type of an enumerator is @int@. Example: \begin{cfa} enum e { A }; sizeof(A) == sizeof(int) $\C{// in C}$ sizeof(A) == sizeof(e) $\C{// in \CC}$ /* and sizeof(int) is not necessary equal to sizeof(e) */ \end{cfa} \item[Rationale:] In \CC, an enumeration is a distinct type. \item[Effect on original feature:] Change to semantics of well-defined feature. \item[Difficulty of converting:] Semantic transformation. \item[How widely used:] Seldom. The only time this affects existing C code is when the size of an enumerator is taken. Taking the size of an enumerator is not a common C coding practice. \end{description} \end{comment}