enum type check in C/gcc

前端 未结 6 946
小鲜肉
小鲜肉 2020-12-03 03:19

See the simple example below. When a function returning one enum is assigned to a variable of a different enum I don\'t get any warning even with <

相关标签:
6条回答
  • 2020-12-03 03:47

    That's because enums in C are simply a group of unique integer constants, that save you from having to #define a whole bunch of constants. It's not like C++ where the enums you create are of a specific type. That's just how C is.

    It's also worth noting that the actual size used to represent enum values depends on the compiler.

    0 讨论(0)
  • 2020-12-03 03:48

    An enum in C is basically handled like an integer. It's just a nicer way to use constants.

      // this would work as well
      ftype = 1;
    

    You can also specify the values:

      enum color {
         RED=0,GREEN,BLUE
      } mycolor;
    
      mycolor = 1; // GREEN
    
    0 讨论(0)
  • 2020-12-03 03:57

    gcc decided not to warn (as does clang) but icc (Intel compiler) would warn in this situation. If you want some additional type checking for enum types, you can pass your code to some static code checker software like Lint that is able to warn in such cases.

    gcc decided it was not useful to warn for implicit conversions between enum types but note also that C doesn't require the implementation to issue a diagnostic in case of an assignment between two different enum types. This is the same as for the assignment between any arithmetic type: diagnostic is not required by C. For example, gcc would also not warn if you assign a long long to a char or a short to a long.

    0 讨论(0)
  • 2020-12-03 03:58

    This declaration:

    enum fruit {
        apple,
        orange
    };
    

    declares three things: a type called enum fruit, and two enumerators called apple and orange.

    enum fruit is actually a distinct type. It's compatible with some implementation-defined integer type; for example, enum fruit might be compatible with int, with char, or even with unsigned long long if the implementation chooses, as long as the chosen type can represent all the values.

    The enumerators, on the other hand, are constants of type int. In fact, there's a common trick of using a bare enum declaration to declare int constants without using the preprocessor:

    enum { MAX = 1000 };
    

    Yes, that means that the constant apple, even though it was declared as part of the definition of enum fruit, isn't actually of type enum fruit. The reasons for this are historical. And yes, it would probably have made more sense for the enumerators to be constants of the type.

    In practice, this inconsistency rarely matters much. In most contexts, discrete types (i.e., integer and enumeration types) are largely interchangeable, and the implicit conversions usually do the right thing.

    enum fruit { apple, orange };
    enum fruit obj;      /* obj is of type enum fruit */
    obj = orange;        /* orange is of type int; it's
                            implicitly converted to enum fruit */
    if (obj == orange) { /* operands are converted to a common type */
        /* ... */
    }
    

    But the result is that, as you've seen, the compiler isn't likely to warn you if you use a constant associated with one enumerated type when you mean to use a different one.

    One way to get strong type-checking is to wrap your data in a struct:

    enum fruit { /* ... */ };
    enum color { /* ... */ };
    struct fruit { enum fruit f; };
    struct color { enum color c; };
    

    struct fruit and struct color are distinct and incompatible types with no implicit (or explicit) conversion between them. The drawback is that you have to refer to the .f or .c member explicitly. (Most C programmers just count on their ability to get things right in the first place -- with mixed results.)

    (typedef doesn't give you strong type checking; despite the name, it creates an alias for an existing type, not a new type.)

    (The rules in C++ are a little different.)

    0 讨论(0)
  • 2020-12-03 03:58

    gcc guys always have a reason not to do somthing.

    Use clang with options -Wenum-conversion -Wassign-enum.

    0 讨论(0)
  • 2020-12-03 04:04

    Probably most of us understand the underlying causes ("the spec says it must work"), but we also agree that this is a cause of a lot of programming errors in "C" land and that the struct wrapping workaround is gross. Ignoring add-on checkers such as lint, here's what we have:

    gcc (4.9): No warning available.
    microsoft cl (18.0): No warning available.
    clang (3.5): YES -Wenum-conversion
    
    0 讨论(0)
提交回复
热议问题