Home > OS >  address of a va_list variable is not allowed? Error: assignment from incompatible pointer type?
address of a va_list variable is not allowed? Error: assignment from incompatible pointer type?

Time:01-23

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 = &ap; // <- 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.

  • Related