Gepard
Gepard

Reputation: 499

Sizeof enumerations

Can someone explain why member X has different size than the enumerated type itself, despite being explicitly defined as LL? It seems counterintuitive that I need to cast (enum e_x)X member of the very same enumerated type to be sure it has the same size as the type.

#include <stdio.h>
#include <limits.h>

enum e_x { X = 0LL, M = LLONG_MAX };

int main() {
 printf("%zu %zu %zu %zu\n",
         sizeof X,
         sizeof((enum e_x)X),
         sizeof(enum e_x),
         sizeof(long long));
}

Output:

 4 8 8 8

Expected:

 8 8 8 8

How can you deal with it when passing enumeration to a function that uses va_arg?

Upvotes: 3

Views: 130

Answers (3)

0decimal0
0decimal0

Reputation: 3984

ISO C restricts the enumerator values to the range of int only .If you need enumeration constants that don't fit into an int you will need to use compiler-specific extensions to do so.

More importantly the compiler is free to choose a smaller type if it can represent the values you define.

Try to compile with -pedantic option, you will get the error.

Upvotes: 0

user1951747
user1951747

Reputation: 71

It sounds like your real issue deals with passing a long long argument to a function with variable arguments:

"How can you deal with it when passing enumeration to a function that uses va_arg?"

You probably can't. In C, functions with variable arguments are limited in the kinds of types they can deal with. Integer types undergo default argument promotion, which changes most or all integral types to int. Here's the best reference I could locate: http://www.eskimo.com/~scs/cclass/int/sx11c.html

If you absolutely need to pass a long long, you could probably pass a pointer to it.

Upvotes: 1

Casey
Casey

Reputation: 42554

The behavior you are expecting is true of C++, but but not C. C does not allow non-int enumerators. From N1570 (~C11) §6.7.2.2/2:

The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.

Paragraph 3 also says:

The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.

Para 4 says:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined

sizeof X == sizeof(int) is a consequence of para 3, presumably sizeof M == 4 as well for the same reason. The implementation apparently chose a 64-bit integer type for the enumeration type so sizeof(enum e_x) == 8 and sizeof((enum e_x)X)) == 8 as well.

Upvotes: 4

Related Questions