Error when pass "enum" in a function with variable arguments
arguments, c
Solution
Variadic arguments to functions are subject to a conversion called default argument promotions: Everything with a conversion rank smaller than that of `int` gets promoted to `int` before passed to a variadic function. And an `enum` has a smaller conversion rank (and may be represented as a `short` or something else in your case). So what your callee sees is an int and must fetch it by `va_arg` as such.
C99 7.15.1.1 p.2 (emphasis mine) about `va_arg`:
[…] If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:
- one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
- [sth. about pointer types]
And 6.7.2.2, p.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, […]
So, the `va_arg(ap, enum drink)` version has no defined bahavior (as far as the C standard is concerned). At least, if the compiler doesn't specify to always use `int` for `enum`s. Hence the warning from `gcc`.
Some coding-guidelines say to avoid `enum` usage for types entirely, using `int` everywhere and only define `enum` constants:
enum {
MUDSLIDE, FUZZY_NAVEL, MONKEY_GLAND, ZOMBIE
};
and
double price(int d);
HTH
Problem
I'm reading the book Head First C and I am the part about the variable arguments. I wrote the following code: ``` #include <stdio.h> #include <stdlib.h> #include <stdarg.h> enum drink { MUDSLIDE, FUZZY_NAVEL, MONKEY_GLAND, ZOMBIE }; double price(enum drink d) { switch(d) { case MUDSLIDE: return 6.79; case FUZZY_NAVEL: return 5.31; case MONKEY_GLAND: return 4.82; case ZOMBIE: return 5.89; } return 0; } double calc(int args, ...) { double total = 0; va_list ap; va_start(ap, args); int i; for (i = 0; i < args; i++) { int currentDrink = va_arg(ap, int); total += price((drink) currentDrink); } va_end(ap); return total; } int main() { printf("Price is %.2f\n", calc(2, MONKEY_GLAND, MUDSLIDE)); return 0; } ``` The code compiles and works perfectly. But... There are two different lines of my solution with the book. My: ``` int currentDrink = va_arg(ap, int); total += price((drink) currentDrink); ``` Book: ``` enum drink currentDrink = va_arg(ap, enum drink); total += price(currentDrink); ``` I tried to use the solution proposed in the book, but the error during execution and reports a warning: 'drink' is promoted to 'int' when passed through '...' The book is used gcc compiler on linux. I am using gcc on Windows. Question: What is the reason I was unable to compile the code proposed in the book? Edit There configured wrong. Was using a C++ compiler was thinking of using a C. But the question remains: why in C++ results in a warning and error in the execution?