Code to duplicate this on Linux is as follows:
GCC 4.8.5 20150623 (Red Hat 4.8.5-44) No i can't change this, it's on CentOS7 and its a requirement to stay there)
#include <stdarg.h>
struct foo {
va_list *pAP;
const char *fmt;
};
void format_output( struct foo *pFoo );
void my_vprintf( const char *fmt, va_list ap )
{
struct foo x;
x.fmt = fmt;
// why is this not allowed?
x.pAP = ≈ // <- ERROR/WARNING: assignment from incompatible pointer type
format_output( &x );
}
void my_printf( const char *fmt, ... )
{
va_list ap;
va_start( ap, fmt );
my_vprintf( fmt, ap );
}
CodePudding user response:
It's not allowed because on your implementation, va_list
happens to be an array type. That's allowed by the standard, but not required. (And it's a bit annoying.)
When you use an array type as a function parameter, it "decays" to a pointer type (a pointer to the first element in the array), which is not compatible with a pointer to the array type (which is what the pAP
member of struct foo
is).
A simple workaround is to create the struct foo
in my_printf
rather than creating it in my_vprintf
. Another possibility is to make the struct foo
member a va_list
rather than a pointer to a va_list
, and use va_copy
rather than assignment.