Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Compare enumerate with invalid value

I would like try to understand how is working the compilator when we compare an enumerate with invalid value, and what the program is doing during execution.

I found strange source code during my work, and did not understand the behaviour of the program, which was not giving me the expected result.

I wrote the following little program to summarize my problem.

I create an enum E_Number and I instanciate a variable a, with the value -1. Then I perform comparison on a to check if it belongs to the range of the enum.

(I know, this is really strange, but this is exactly what i found in source code !)

I expected the result tells me Not in range because of the fail of the first condition (a >= FIRST_ENUM). But it was the fail of the second condition (a < NB_MAX_NUMBER) which gave me the right result (see the printf())...

If I cast a in (int) in the if conditions, I get excepted results.

So what is happening during the execution ? Is the program considering -1 as an other possible enum value which will be positionned after NB_MAX_NUMBER ? What is the rule for > and < operator on enum ?

#include <stdio.h>

#define FIRST_ENUM 0
typedef enum{
    NUM_1 = FIRST_ENUM, 
    NUM_2, 
    NUM_3,
    NB_MAX_NUMBER
}E_Number; 

int main()
{
    E_Number a = -1; 

    if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
    {
        printf("In Range\n"); 
    }
    else
    {
        printf("Not in Range\n"); 
    }

    printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE"); 
    printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE"); 

    return 0; 
}

gcc program.c

.\a.exe
Not in Range
1st condition = TRUE
2nd condition = FALSE

I am working with MINGW compilator ( gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.2 )

like image 887
GOoOGle Avatar asked Feb 27 '26 00:02

GOoOGle


1 Answers

In your case the compiler consider E_Number as unsigned int because all the legal values are unsigned, so -1 is considered to be ~0u which is >= FIRST_ENUM and < NB_MAX_NUMBER

I have the same behavior with gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1)

pi@raspberrypi:~ $ ./a.out 
Not in Range
1st condition = TRUE
2nd condition = FALSE

But, if I change your definitions like that :

#include <stdio.h>

#define FIRST_ENUM -1
typedef enum{
    NUM_1 = FIRST_ENUM, 
    NUM_2, 
    NUM_3,
    NB_MAX_NUMBER
}E_Number; 

int main()
{
    E_Number a = -2; 

    if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
    {
        printf("In Range\n"); 
    }
    else
    {
        printf("Not in Range\n"); 
    }

    printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE"); 
    printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE"); 

    return 0; 
}

the behavior change and the enum is considered to be an int and I have :

pi@raspberrypi:~ $ ./a.out 
Not in Range
1st condition = FALSE
2nd condition = TRUE
like image 133
bruno Avatar answered Mar 01 '26 15:03

bruno