Reputation: 499
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
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
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
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