Question: 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.)?

Answer: 
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`](http://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion).

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`](http://en.cppreference.com/w/cpp/utility/variadic/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*](https://en.wikipedia.org/wiki/Type_punning) instead.
If I understand your question correctly:

C performs certain "casts" by default when calling a variadic function. GCC calls these [default argument promotions](https://www.gnu.org/software/libc/manual/html_node/Calling-Variadics.html). They are:

* Signed or unsigned `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.