Reputation: 1981
I'm doing some research about variadic functions and arguments.
I noticed that va_arg is able to cast objects into other objects. For example, when the next argument is a char
, but you are using va_arg
like it should be an int
, it casts the char
to an int
:
Function call:
AddNumbers(3, 5, 'a', 20);
Function declaration:
int AddNumbers(int count, ...) {
int result;
va_list va;
va_start(va, count);
for(int i = 0; i < count; ++i) {
result += va_arg(va, int);
}
return result;
}
So my question is: what kind of casting does this function use (C-style, dynamic_cast, etc.)?
Upvotes: 2
Views: 1643
Reputation: 149185
It is not exactly casting, because va_arg
is a macro, not a function. So the type of va_arg(va, int)
is by construction int
.
But promotions do occur when calling the variadic function (except for the argument preceding the ellipsis.
So in AddNumbers(3, 5, 'a', 20);
, the character 'a
' is promoted to an int. You can then either use it as an int as your code does, or convert it back to a char (a conversion not a cast) which is defined because the int value can be represented as a char (by construction)
Upvotes: 1
Reputation: 409472
It has nothing to do with casting. In this case it works because of argument promotion.
When you use a varargs function, integer types smaller than int
(like e.g. char
) are promoted to int
.
That's why it works when passing character literals to the function. If you try some other type, like e.g. a floating point value, then it will no longer work.
As for what the va_arg
macro (it's mostly implemented as a macro) does, it is totally implementation dependent. It might not do any casting at all, but use some other form of type punning instead.
Upvotes: 4
Reputation: 58442
If I understand your question correctly:
C performs certain "casts" by default when calling a variadic function. GCC calls these default argument promotions. They are:
char
and short int
become signed or unsigned int
.float
becomes double
.This isn't really a matter of va_arg
doing a cast within AddNumbers
; instead, when calling AddNumbers
, the caller promotes the arguments to AddNumbers
as part of pushing them onto the stack for AddNumbers
to use.
Upvotes: 1