0

In C++, I see

#include <iostream>

typedef enum {
    NORMAL = 0,
    EXTENDED
} CyclicPrefixType_t;

void func (CyclicPrefixType_t x) {
    if(x < NORMAL){
        printf ("lower\n");
    }else{
        printf ("higher\n");
    }
}

int main (void) {
    //MUST CAST OR WE GET ERROR
    CyclicPrefixType_t cpType = CyclicPrefixType_t(NORMAL - 1);

    func (cpType);
    return 0;
}

Run the code on C++

Expected: lower > It is OK

But in C,

#include <stdio.h>

typedef enum {
    NORMAL = 0,
    EXTENDED
} CyclicPrefixType_t;

void func (CyclicPrefixType_t x) {
    if(x < NORMAL){
        printf ("lower\n");
    }else{
        printf ("higher\n");
    }
}

int main (void) {
    //NO NEED TO CAST
    CyclicPrefixType_t cpType = (NORMAL - 1);

    func (cpType);
    return 0;
}

Run the code on C

Actually Result: Higher > It is NOT OK

In this case, (-1) is automatically cast to another value. Anyone can tell me which value is here and how it is converted to Because if you print it(%d), It will still (-1)

Bomber Cubit
  • 70
  • 1
  • 5
sun1211
  • 632
  • 5
  • 10
  • In C an `enum`'s underlying type could be unsigned. Can't remember if that's true in C++ – user4581301 Jul 28 '21 at 05:02
  • @user4581301 In fact underlying type is implementation defined. – kiran Biradar Jul 28 '21 at 05:03
  • 7
    "Doctor, it hurts when I do that" --- "Don't do that, then". – n. 1.8e9-where's-my-share m. Jul 28 '21 at 05:53
  • 2
    Additionally, C and C++ are different languages, with different standards defining different behavior. – the busybee Jul 28 '21 at 05:54
  • 1
    `if you print it, It will still (-1)` how did you print it? `printf` doesn't know the type of the argument so it's UB. You must use `std::cout` instead – phuclv Jul 28 '21 at 06:00
  • When you decide the `enum` is `unsigned int` in c++. It will return high as well. [Demo](https://godbolt.org/z/v1eY6zaxs) – Louis Go Jul 28 '21 at 06:00
  • `%d` assumes the stacked value given is a signed `int`, regardless of what you placed there or whether it is the right size. It believes that `%d` is the truth. The compiler, however, *might* issue a warning about mismatching types. – Weather Vane Jul 28 '21 at 06:27
  • 1
    [C11 6.7.2.2p4](http://port70.net/~nsz/c/c11/n1570.html#6.7.2.2): *Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, ...* – pmg Jul 28 '21 at 06:37
  • @user4581301: Re “Either way, assigning an unknown value to an `enum` is verboten”: [In both C and C++, an `enum` object may have values other than the named values.](https://stackoverflow.com/questions/68118192/when-is-the-compiler-allowed-to-optimize-away-a-validity-check-of-an-enum-or-enu/68118407#68118407) And assigning −1 to an `enum` is well defined subject to the selection of the underlying type. If it is a signed type, the assigned value is −1. If it is an unsigned type, it is wrapped. – Eric Postpischil Jul 28 '21 at 13:01

1 Answers1

-1

In C, enum values are integers... and this permits all sorts of undesirable behaviours and programmer misdemeanours (either intended or unintended)

For example, while the C language doesn't provide a next or previous operator, some people think that + and - provide that... but no, these merely add one or subtract one from the underlying value - even if that gives you a value that is not a valid member of the enumeration set.

Generally, it is unwise to rely on the underlying values of enumerations... not least because the compilers have a habit of optimising the value ranges unless they are really needed to be what they are specified to be.

It is not applicable here, but if you really need the numbers to mean something, you may be better off using #define.

Andrew
  • 1,781
  • 1
  • 21
  • 33