Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope of enum in C vs C++

Tags:

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 <stdio.h> 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; } 

It compiles and runs fine in C.

But in C++ it fails in compilation.

#include <iostream> 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; } 

[Error] 'INT' was not declared in this scope

Are enum and scope rules different in C and C++?

like image 506
Destructor Avatar asked May 05 '15 07:05

Destructor


People also ask

What is the scope of enum in C?

In C, there is simply no rule for scope for enums and struct. The place where you define your enum doesn't have any importance. In C++, define something inside another something (like an enum in a class) make this something belong to the another something.

What is the scope of enum?

In an unscoped enum, the scope is the surrounding scope; in a scoped enum, the scope is the enum-list itself. In a scoped enum, the list may be empty, which in effect defines a new integral type. By using this keyword in the declaration, you specify the enum is scoped, and an identifier must be provided.

What is the advantage of enum in C?

The benefits of using enumerations include: Reduces errors caused by transposing or mistyping numbers. Makes it easy to change values in the future. Makes code easier to read, which means it is less likely that errors will creep into it.

When should I use enum in C?

Enumeration or Enum in C is a special kind of data type defined by the user. It consists of constant integrals or integers that are given names by a user. The use of enum in C to name the integer values makes the entire program easy to learn, understand, and maintain by the same or even different programmer.


2 Answers

In C, there is simply no rule for scope for enums and struct. The place where you define your enum doesn't have any importance.

In C++, define something inside another something (like an enum in a class) make this something belong to the another something.

If you want to make your enum global in C++, you will have to define it outside your class, or access from your struct path:

#include <iostream> struct mystruct {     enum {INT, FLOAT, STRING} type;     int integer;     float floating_point; } tu;  int main() {     tu.type = mystruct::INT; // INT is not in global scope, I have to precise it.     tu.integer = 100;     return 0; } 

Note: This works in this exemple, because you are using a struct, where everything is public by default. Be careful; you can access your enum type and values from outside your struct or your class only if the enum is in a public scope, as any field or function.

like image 94
Aracthor Avatar answered Oct 08 '22 17:10

Aracthor


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 <stdio.h> 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 <iostream> 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; 
like image 26
Vlad from Moscow Avatar answered Oct 08 '22 17:10

Vlad from Moscow