J
Joerg Schoen
Hi folks!
I have a function that gets a 'va_list'. I am passing the
'va_list' two times to a function like 'vprintf' to print
it out.
I thought that this was portable until I came across a
platform (AS/400) where it fails: The 'va_list' is actually
defined as some some kind of an array, so passing it happens
by *reference*: The first user will destroy it and the second
time it does not work.
My question is: Does the standard allow this and AS/400 is
broken or am I invoking undefined behaviour?
Below is a test program
---------------- snip --------------------------
/*
* Test if a va_list argument can be used to traverse the
* variable arguments more than once.
*/
#include <stdio.h>
#include <stdarg.h>
static void scanargs(int dest[2],va_list ap)
{
dest[0] = va_arg(ap,int);
dest[1] = va_arg(ap,int);
}
static void teststdarg(int dest[4], ...)
{
va_list ap;
va_start(ap,dest);
scanargs(dest,ap);
scanargs(dest + 2,ap);
va_end(ap);
}
int main(int argc,char *argv[])
{
int a[4];
teststdarg(a,1,2,3,4);
if((a[0] == 1 && a[1] == 2) &&
(a[2] == 1 && a[3] == 2) || (a[2] == 3 && a[3] == 4)) {
if(a[2] == 1)
printf("We can use a 'va_list' at least twice.\n");
else
printf("WARNING: Reusing 'va_list' gives different results!\n");
} else {
fprintf(stderr,"ERROR: Something is very bad here!\n");
exit(20);
}
return 0;
}
---------------- snap --------------------------
I have a function that gets a 'va_list'. I am passing the
'va_list' two times to a function like 'vprintf' to print
it out.
I thought that this was portable until I came across a
platform (AS/400) where it fails: The 'va_list' is actually
defined as some some kind of an array, so passing it happens
by *reference*: The first user will destroy it and the second
time it does not work.
My question is: Does the standard allow this and AS/400 is
broken or am I invoking undefined behaviour?
Below is a test program
---------------- snip --------------------------
/*
* Test if a va_list argument can be used to traverse the
* variable arguments more than once.
*/
#include <stdio.h>
#include <stdarg.h>
static void scanargs(int dest[2],va_list ap)
{
dest[0] = va_arg(ap,int);
dest[1] = va_arg(ap,int);
}
static void teststdarg(int dest[4], ...)
{
va_list ap;
va_start(ap,dest);
scanargs(dest,ap);
scanargs(dest + 2,ap);
va_end(ap);
}
int main(int argc,char *argv[])
{
int a[4];
teststdarg(a,1,2,3,4);
if((a[0] == 1 && a[1] == 2) &&
(a[2] == 1 && a[3] == 2) || (a[2] == 3 && a[3] == 4)) {
if(a[2] == 1)
printf("We can use a 'va_list' at least twice.\n");
else
printf("WARNING: Reusing 'va_list' gives different results!\n");
} else {
fprintf(stderr,"ERROR: Something is very bad here!\n");
exit(20);
}
return 0;
}
---------------- snap --------------------------