Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

611
Views
C (gnu11) enum variable can't compare to int?

This seems really weird to me, and I've never seen any discussion of it in resources about C enums. The variable a is of type enum Direction, and it can be -1, but a<0 will be false. What am I missing about enums?

#include <stdio.h>

enum Direction {N,W,S,E};

int main()
{
    enum Direction a = N;
    printf("a is %d\n", a);
    a--;
    printf("now a is %d\n", a);
    printf("but (a<0) is %d\n\n", (a<0));
    
    int b = N;
    printf("b is %d\n", b);
    b--;
    printf("now b is %d\n", b);
    printf("and (b<0) is %d\n", (b<0));
 
    return 0;
}

The output is

a is 0
now a is -1
but (a<0) is 0

b is 0
now b is -1
and (b<0) is 1
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

The underlying type of an enum is an implementation-defined integer type that can represent all items of the enum. Here, it could be char, int, unsigned int (possibly others).

Your implementation apparently chose to use unsigned int ; it's consistent with the comparison to 0 (can't be negative), and you only have it printed as -1 because in 2-complement, -1 has the same representation as "largest unsigned of the same width" (which is the value you have, because unsigned 0 minus 1 will wrap to the largest value).

It only prints as -1 because of the %d format of printf, which converts it back to signed. But because it's unsigned, you should have used %u.

When you convert it to a signed integer by creating an int var, you have an actual int, so it behaves correctly (printed as -1 by the %d format of printf).

over 4 years ago · Santiago Trujillo Report

0

It depends on what integer type is selected by the compiler to be compatible with the enumeration type. The compiler can select an unsigned integer type.

In this statement

printf("now a is %d\n", a);

you are using the conversion specifier %d designed for signed integer types though the enumeration can be compatible with an unsigned integer type and if you will use the conversion specifier %u you will get another result.

If for example you will declare an enumeration constant as having a negative value then the compiler will select a signed integer type as compatible with the enumeration.

Here are two demonstrative programs that show the difference

#include <stdio.h>

int main( void )
{
    enum Direction {N,W,S,E};
    
    enum Direction a = N;
    
    --a;
    
    printf( "a < 0 is %d\n", a < 0 );
}

The output of this program is

a < 0 is 0

The compiler selected an unsigned integer type as the compatible integer type.

#include <stdio.h>

int main( void )
{
    enum Direction {N = -1, W,S,E};
    
    enum Direction a = W; // W is equal to 0
    
    --a;
    
    printf( "a < 0 is %d\n", a < 0 );
}

The output of this program is

a < 0 is 1

because the compiler selected a signed integer type as the compatible integer type.

Form the C Standard (6.7.2.2 Enumeration specifiers)

4 Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,128) but shall be capable of representing the values of all the members of the enumeration. T

That is there is a difference between an enumeration type and an enumeration constant. Enumeration constants always have the type int. But enumeration types are compatible with integer types (signed or unsigned) selected by the compiler.

Compare the two calls of printf in this demonstration program.

#include <stdio.h>

int main( void )
{
    enum Direction {N,W,S,E};
    
    enum Direction a = N;
    
    printf( "a - 1 < 0 is %d\n", a - 1 < 0 );
    printf( "N - 1 < 0 is %d\n", N - 1 < 0 );
}

where the program output is

a - 1 < 0 is 0
N - 1 < 0 is 1
over 4 years ago · Santiago Trujillo Report

0

The pitfall is your format specifier when printing a. The format specifier %d lets printf interpret a as a signed integer, no matter what data type it actually is. But actually, it is an unsigned integer, and a-- resulted in an overflow, i.e. a == 4294967295. Hence a < 0 is false. When interpreting this value as a signed integer, it is -1. Try using %u as format specifier when printing a and you will see the real value of a.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!