Why are enum values accessible outside the block in which enum is defined in C, but not in C++?
Consider the following C program.
#include
The main difference is that opposite to C, C++ has a class scope.
In C (6.2.1 Scopes of identifiers)
4 Every other identifier has scope determined by the placement of its declaration (in a declarator or type specifier). If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit.
Thus in this program
#include
struct mystruct
{
enum {INT, FLOAT, STRING} type;
int integer;
float floating_point;
} tu;
/* Why is INT accessible here? */
int main()
{
tu.type = INT;
tu.integer = 100;
return 0;
}
Enumerators INT, FLOAT, STRING are declared outside any block scope and therefore have the file scope.
In C++ there is defined a separate scope - class scope:
3.3.7 Class scope
1 The following rules describe the scope of names declared in classes. 1) The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, default arguments, exception-specifications, and brace-or-equal-initializers of non-static data members in that class (including such things in nested classes).
and
2 The name of a class member shall only be used as follows:
— in the scope of its class (as described above) or a class derived (Clause 10) from its class,
— after the . operator applied to an expression of the type of its class (5.2.5) or a class derived from its class,
— after the -> operator applied to a pointer to an object of its class (5.2.5) or a class derived from its class,
— after the :: scope resolution operator (5.1) applied to the name of its class or a class derived from its class.
Take into account that (9.2 Class members)
1 ...Members of a class are data members, member functions (9.3), nested types, and enumerators.
Thus in this program
#include
struct mystruct
{
enum {INT, FLOAT, STRING} type;
int integer;
float floating_point;
} tu;
/* Why is INT accessible here? */
int main()
{
tu.type = INT; // Invalid access of class member
tu.integer = 100;
return 0;
}
You shall access class member INT
in one of the following ways.
tu.type = mystruct::INT;
or
tu.type = tu.INT;
or even like
tu.type = ( &tu )->INT;