Scope of enum in C vs C++

后端 未结 3 1656
别跟我提以往
别跟我提以往 2021-01-01 15:53

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 

        
相关标签:
3条回答
  • 2021-01-01 16:08

    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.

    0 讨论(0)
  • 2021-01-01 16:08

    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;
    
    0 讨论(0)
  • 2021-01-01 16:08

    The answers given by Vlad and Arachtor are good as far as they go, but there is a question they do not address: why C++ does it differently. If someone is familiar with Stroustrup's book, they may be able to improve this, but I suppose:

    • C was designed long ago to be fairly easy to compile, while C++ aims to make programming more reliable by using OO, whose main ideal is “in one place, tell the user of a construct all they need to know to use it and no more”; this has the often unspoken benefit of bringing together what belongs together.
    • This leads to the decisions to use type definitions to limit the scope of some definitions, and to place constructs within a hierarchy of namespaces.
    • By restricting the scope of a nested enum it is possible to use shorter names without risk of ambiguity or clashes.
    0 讨论(0)
提交回复
热议问题