What is the defined behavior for something like the following?
#include <stdio.h>
typedef enum {
ENUM_VAL_1 = 1,
ENUM_VAL_2 = 2
} TEST_ENUM;
int main() {
TEST_ENUM testVar1 = ENUM_VAL_1;
TEST_ENUM ENUM_VAL_1 = ENUM_VAL_1;
TEST_ENUM testVar2 = ENUM_VAL_1;
printf("ENUM_VAL_1 = %u\n",ENUM_VAL_1);
printf("testVar1 = %u\n",testVar1);
printf("testVar2 = %u\n",testVar2);
return 0;
}
From my testing with both GCC and MSVC compilers, the behavior of this is that testVar1 will be set equal to the enumeration value "ENUM_VAL_1" or 1. However, the next statement will try to set the variable ENUM_VAL_1 equal to its own value, which is of course current uninitialized and thus garbage, instead of setting the variable ENUM_VAL_1 equal to the enumeration value ENUM_VAL_1. Then, of course, testVar2 will also get the same garbage value as the variable ENUM_VAL_1.
What is the defined behavior of this according to the C standards, or is this undefined behavior? Whether or not it is defined, I'm guessing this type of example is bad practice at very least due to the ambiguity.
Thanks!
It can be created in two types:- It can be declared during declaring enumerated types, just add the name of the variable before the semicolon.or, Beside this, we can create enumerated type variables as same as the normal variables. By default, the starting code value of the first element of enum is 0 (as in the case of array) .
Enumerator types of values are also known as enumerators. It is also assigned by zero the same as the array. It can also be used with switch statements. For example: If a gender variable is created with value male or female.
1 Two enum names can have same value. For example, in the following C program both ‘Failed’ and ‘Freezed’ have same value 0. ... 2 If we do not explicitly assign values to enum names, the compiler by default assigns values starting from 0. ... 3 We can assign values to some name in any order. ... More items...
By default, the values // of the constants are as follows: // constant1 = 0, constant2 = 1, constant3 = 2 and // so on. enum flag {constant1, constant2, constant3, ....... }; Variables of type enum can also be defined. They can be defined in two ways:
According to the C Standard (6.2.1 Scopes of identifiers)
- ... If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
And
7 Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator
So in this declaration
TEST_ENUM ENUM_VAL_1 = ENUM_VAL_1;
declarator ENUM_VAL_1
is considered completed before the sign =. So it hides the enumerator.
In fact it is initialized by itself and has an indeterminate value.
The same is valid for C++ (3.3.2 Point of declaration)
1 The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value. —end example ]
I expected the TEST_ENUM ENUM_VAL_1 = ENUM_VAL_1;
line to fail to compile, but it does. I changed the assigned value to ENUM_VAL_2
, and the printing then gives ENUM_VAL_1 = 2
, testVar1 = 1
and testVar2 = 2
, so ENUM_VAL_1
is a local variable.
It is actually a routine scoping issue; it means that the variable declaration in main()
shadows the declaration outside — and if the typedef
were within main()
, the code would not compile. Add -Wshadow
to your compilation options to see the shadowing. After setting testVar1
, ENUM_VAL_1
means the local variable, not the enumeration constant. Initializing a variable with itself doesn't really initialize the variable; it copies undefined garbage into the value.
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