When trying to compile this code

```
#include <stdarg.h>

void bar_ptr(int n, va_list *pvl) {
    // do va_arg stuff here
}

void bar(int n, va_list vl) {
    va_list *pvl = &vl; // error here
    bar_ptr(n, pvl);
}

void foo(int n, ...) {
    va_list vl;
    va_list *pvl = &vl; // fine here
    va_start(vl, n);
    bar(n, vl);
    va_end(vl);
}

int main() {
    foo(3, 1, 2, 3);
    return 0;
}

```

the GCC compiler prints a warning about `initialization from incompatible pointer type` in the `bar` function. The identical statement is fine in `foo`.

It seems that the type of an agument of type `va_list` is not a `va_list`. This can be tested easily with a static assertion like

```
_Static_assert(sizeof(vl) == sizeof(va_list), "invalid type");

```

in the `bar` function. With GCC, the `_Static_assert` fails. The same can be tested also in C++ with `declytpe` and `std::is_same`.

I would like to take the address of the `va_list vl` argument of `bar`, and pass it as argument of `bar_ptr`, to do thinks like the one described in this [thread](https://stackoverflow.com/questions/3369588/pass-va-list-or-pointer-to-va-list). On the other hand, it is fine to call `bar_ptr(n, pvl)` directly from `main`, replacing `bar(n, vl)`.

According to the footnote 253 of the [C11 final draft](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf),

> 
> It is permitted to create a pointer to a `va_list` and pass that
>  pointer to another function
> 
> 
> 

Why this cannot be done if `va_list` is defined as argument of the function, and not in the function body?

**Workaround:**

Even if this does not answer the question, a possible workaround is to change the content of `bar` by using a local copy of the argument created with va\_copy:

```
void bar(int n, va_list vl) {
    va_list vl_copy;
    va_copy(vl_copy, vl);
    va_list *pvl = &vl_copy; // now fine here
    bar_ptr(n, pvl);
    va_end(va_copy);
}

```