\chapter{C Enumeration in \texorpdfstring{\CFA}{Cforall}} \CFA supports legacy C enumeration using the same syntax for backward 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{Visibility} \label{s:CVisibility} 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. For example, enumerator First from E1 can exist at the scope as First from E2. 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@. Aside, name shadowing in \CFA only happens when a name has been redefined with the exact same type. Because an enumeration define its type and enumerators in one definition, and enumeration cannot be changed afterward, shadowing an enumerator is not possible (it is impossible to have another @First@ with same type @E1@.). \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{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 introduce enumerators from a scoped enumeration to a block scope 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:CVisibility}, 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. \section{Type Safety} \label{s:TypeSafety} 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. However, 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 and provides the same workaround cast: \begin{cquote} \begin{description}[leftmargin=*,topsep=0pt,itemsep=0pt,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} \hfill ISO/IEC 14882:1998 (\CC Programming Language Standard)~\cite[C.1.5.7.2.5]{ANSI98:C++} \end{cquote}