Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

613
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda