A good post on this topic is here:
enum type check in C/gcc - Stack Overflow
If you want to type check in gcc, you can do it but it requires quite a bit of boilerplate. The following will produce warnings if you try to drink a food or eat a beverage (type mismatch)
Code:
#include <stdio.h>
enum food_type {
FOOD_UNKNOWN,
FOOD_CARROTS,
FOOD_CAKE,
FOOD_ICECREAM,
};
#define FOOD_UNKNOWN (enum food_type)FOOD_UNKNOWN
#define FOOD_CARROTS (enum food_type)FOOD_CARROTS
#define FOOD_CAKE (enum food_type)FOOD_CAKE
#define FOOD_ICECREAM (enum food_type)FOOD_ICECREAM
enum beverage_type {
BEVERAGE_UNKNOWN,
BEVERAGE_COLA,
BEVERAGE_WATER,
BEVERAGE_COFFEE,
};
#define BEVERAGE_UNKNOWN (enum beverage_type)BEVERAGE_UNKNOWN
#define BEVERAGE_COLA (enum beverage_type)BEVERAGE_COLA
#define BEVERAGE_WATER (enum beverage_type)BEVERAGE_WATER
#define BEVERAGE_COFFEE (enum beverage_type)BEVERAGE_COFFEE
#define CHECK_TYPE(TYPE, X) \
({ TYPE __dummy; \
typeof(X) __dummy2; \
(void)(&__dummy == &__dummy2); \
1; \
})
#define eat_food(FOOD) do { \
CHECK_TYPE(enum food_type, FOOD); \
eat_food_(FOOD); \
} while(0)
#define drink_beverage(BEVERAGE) do { \
CHECK_TYPE(enum beverage_type, BEVERAGE); \
drink_beverage_(BEVERAGE); \
} while(0)
void eat_food_(enum food_type ft)
{
const char *ft_str;
switch (ft) {
case FOOD_CARROTS:
ft_str = "Carrots";
break;
case FOOD_CAKE:
ft_str = "Cake";
break;
case FOOD_ICECREAM:
ft_str = "Ice Cream";
break;
default:
ft_str = "Unknown Foods";
break;
}
printf("You are eating %s\n", ft_str);
}
void drink_beverage_(enum beverage_type bt)
{
const char *bt_str;
switch (bt) {
case BEVERAGE_COLA:
bt_str = "Cola";
break;
case BEVERAGE_WATER:
bt_str = "Water";
break;
case BEVERAGE_COFFEE:
bt_str = "Coffee";
break;
default:
bt_str = "Unknown Beverages";
break;
}
printf("You are drinking %s\n", bt_str);
}
int main()
{
eat_food(FOOD_CARROTS);
drink_beverage(BEVERAGE_COFFEE);
eat_food(BEVERAGE_WATER); /* wrong type */
drink_beverage(FOOD_CAKE); /* wrong type */
return 0;
}
The warning generated will stop you because the macro eat_food expands to first call the CHECK_TYPE macro, which will try to compare pointers of distinct types without a cast. Its quite a roundabout way but it might be useful if you have a multitude of different enumerated types and want to keep them separate. Notice however that you have to define the enumeration constants twice (once with the preprocessor, and once without), and the "typeof" keyword is probably only in gcc.