1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
// For enum's underlying/compatible type:
// std C: unspecified
// GCC: 'unsigned int' if no negative values,
// otherwise 'int' (see GCC manul 4.9).
// But also accept ulong, long
// For the type of the enumerators:
// std C: 'int'
// GCC: 'int' if the value fit in a 'int'
// otherwise same as the enum underlying type?
//
// The following tests match GCC's choices
#define is_unsigned(X) ((typeof(X))-1 > 0)
enum u {
U = 1U, // fit in 'int'
// no negatives
};
_Static_assert(sizeof(enum u) == sizeof(int), "size");
_Static_assert(is_unsigned(enum u), "enum u");
_Static_assert(is_unsigned(U) == 0, "value U"); // fail
enum v {
V = __INT_MAX__ + 1U, // doesn't fit in 'int'
// no negatives
};
_Static_assert(sizeof(enum v) == sizeof(int), "size");
_Static_assert(is_unsigned(enum v), "enum v");
_Static_assert(is_unsigned(V) == 1, "value V");
enum w {
W = __LONG_MAX__ + 1UL, // doesn't fit in 'long'
};
_Static_assert(sizeof(enum w) == sizeof(long), "size");
_Static_assert(is_unsigned(enum w), "enum w");
_Static_assert(is_unsigned(W) == 1, "value W");
enum x {
A = 1, // fit in 'int'
B = 0x100000000UL, // doesn't fit in int
};
_Static_assert(sizeof(enum x) == sizeof(long), "size");
_Static_assert(is_unsigned(enum x), "enum x");
_Static_assert(sizeof(A) == sizeof(int), "size A"); // fail
_Static_assert(is_unsigned(A) == 0, "enum A"); // fail
_Static_assert(sizeof(B) == sizeof(long), "size B");
_Static_assert(is_unsigned(B) == 1, "enum B");
enum y {
C = 1, // fit in 'int'
D = 0x100000000L, // doesn't fit in int
};
_Static_assert(sizeof(enum y) == sizeof(long), "size");
_Static_assert(is_unsigned(enum y), "enum y");
_Static_assert(sizeof(C) == sizeof(int), "size C"); // fail
_Static_assert(is_unsigned(C) == 0, "enum C"); // fail
_Static_assert(sizeof(D) == sizeof(long), "size D");
_Static_assert(is_unsigned(D) == 1, "enum D");
/*
* check-name: enum-sign-gcc
* check-command: sparse -m64 $file
* check-assert: sizeof(long) == 8
*/
|