Why is the following printing EOF
as the output and not ILLEGAL
? If I remove the initialization for EOF to NULL character, it works as expected. Can't understand what is happening here?
public enum TokenType {
ILLEGAL,
EOF= '\0',//remove the initialization to have it work as expected
IDENT,
INT
};
void Main()
{
Console.WriteLine(TokenType.ILLEGAL);//Prints EOF. Should have printed ILLEGAL
}
By initializing the EOF
value with '\0' you give it a value of 0
.
You can see this in this example:
Console.WriteLine(Convert.ToInt16(TokenType.EOF));
Console.WriteLine($"IntValue: {Convert.ToInt16('\0')}");
0
IntValue: 0
Internally the enum will get values starting from 0 on counting upwards in integers. So below the surface your enum looks like this:
public enum TokenType
{
ILLEGAL = 0,
EOF = 1
IDENT = 2,
INT = 3
};
But you chose to enforce a 0
on the value EOF
! So you have 2 enum names representing the same value. The compiler simply takes the first one that it can find.
First, note that = '\0'
is the same as = 0
. This is because'\0'
has the numerical value of 0. Your enum has the default underlying type of int
. The constant expression '\0'
is converted to the int
of 0
at compile time.
Second, as per the language spec, note that enum members can have duplicated associated values.
Third, from the the same section of the language spec,
The associated value of an enum member is assigned either implicitly or explicitly. [...] If the declaration of the enum member has no initializer, its associated value is set implicitly, as follows:
If the enum member is the first enum member declared in the enum type, its associated value is zero.
Otherwise, the associated value of the enum member is obtained by increasing the associated value of the textually preceding enum member by one. This increased value must be within the range of values that can be represented by the underlying type, otherwise a compile-time error occurs.
So if I were to write out your enum's members' associated values explicitly, it would be:
public enum TokenType {
ILLEGAL = 0,
EOF = 0,
IDENT = 1,
INT = 2
};
ILLEGAL
and EOF
have the same associated value.
Fourth, Console.WriteLine
calls ToString
on your enum. Now look at what Enum.ToString
does (in the Notes to Callers section):
If multiple enumeration members have the same underlying value and you attempt to retrieve the string representation of an enumeration member's name based on its underlying value, your code should not make any assumptions about which name the method will return.
So, it outputting ILLEGAL
is completely normal, as you "should not make any assumptions about which name the method will return".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With