#include <stdarg.h>
void foo(va_list *arg)
{
/* do some stuff which conditionally might read parameters off arg */
}
void bar(va_list arg)
{
foo(&arg);
}
Yet when I compile this on a powerpc linux box with gcc I get the following:
markg@home ~/work/ffdev $ gcc -ansi -pedantic -Wall -W -O -c t.c
t.c:3: warning: unused parameter 'arg'
t.c: In function `bar':
t.c:9: warning: passing arg 1 of `foo' from incompatible pointer type
I don't care about the unused argument warning since obviously the real
code is rather more complex and uses it, it is the incompatible pointer
type warning I believe is wrong.
Am I correct in thinking this should work?
The real code is something like a printf function and foo is a function
for handling a format specifier where it conditionally wants to pull
further arguments off the argument list. Any good alternative solutions
to this problem will be welcome.
This is not my code, but I'm maintaining it and life would be easier for
me if it built cleanly on my powerpc Linux box. It builds cleanly with
gcc on x86.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
> As my understanding, the type of va_list should be "char*",
Even without any context (a pox on Google Groups!), your understanding
is wrong...
> I think you might use it as the type of "char*" as where you use it,
> it is just a pointer in 4 bytes when it's compiled.
...as is your assumption about the size of either va_list or char *.
Richard
> Reading the standard, va_list is an object type (, so I believe the
> following should be possible:
>
> #include <stdarg.h>
>
> void foo(va_list *arg)
> {
> /* do some stuff which conditionally might read parameters off arg */
> }
>
> void bar(va_list arg)
> {
> foo(&arg);
> }
>
> Yet when I compile this on a powerpc linux box with gcc I get the following:
> markg@home ~/work/ffdev $ gcc -ansi -pedantic -Wall -W -O -c t.c
> t.c:3: warning: unused parameter 'arg'
> t.c: In function `bar':
> t.c:9: warning: passing arg 1 of `foo' from incompatible pointer type
AFAICT your belief is correct, and gcc is wrong.
Richard
Which version of gcc? I do not get the warning in either gcc 2.95.2 or
gcc 4.0.2.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Looks like a problem with the compiler to me (which honestly wouldn't
be a surprise to me in this case), what build of gcc are you using?
Robert Gamble
$ gcc -v
Reading specs from /usr/lib/gcc/powerpc-unknown-linux-gnu/3.4.5/specs
Configured with: /var/tmp/portage/gcc-3.4.5-r1/work/gcc-3.4.5/configure
--prefix=/usr --bindir=/usr/powerpc-unknown-linux-gnu/gcc-bin/3.4.5
--includedir=/usr/lib/gcc/powerpc-unknown-linux-gnu/3.4.5/include
--datadir=/usr/share/gcc-data/powerpc-unknown-linux-gnu/3.4.5
--mandir=/usr/share/gcc-data/powerpc-unknown-linux-gnu/3.4.5/man
--infodir=/usr/share/gcc-data/powerpc-unknown-linux-gnu/3.4.5/info
--with-gxx-include-dir=/usr/lib/gcc/powerpc-unknown-linux-gnu/3.4.5/include/g++-v3
--host=powerpc-unknown-linux-gnu --build=powerpc-unknown-linux-gnu
--disable-altivec --enable-nls --without-included-gettext
--with-system-zlib --disable-checking --disable-werror
--disable-libunwind-exceptions --disable-multilib
--enable-languages=c,c++,java,f77 --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu
Thread model: posix
gcc version 3.4.5 (Gentoo 3.4.5-r1, ssp-3.4.5-1.0, pie-8.7.9)
Note that this is running on a iMac, so it is ppc rather than x86. They
may be doing things differently.
Sounds like it might be worth raising a bug report on it.
Thanks Dik, also thanks to Richard Bos.
It seems that the bugzilla search engine is not very good. Using va_list
as a search term did not find the relevant bug, which is
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14557
Someone else did and marked my bug as a duplicate. Others have been
caught by this as well!
Apparently, on some implementations (including mine) va_list is
implemented as an array. Let's say the definition of va_list is:
typedef __va_type va_list[10];
Since arrays are not really passed, only a pointer to the first element,
this makes my code equivalent to:
#include <stdarg.h>
void foo(va_list *arg)
{
/* do some stuff which conditionally might read parameters off arg */
}
void bar(__va_type *arg)
{
foo(&arg);
}
So I'm passing a pointer to pointer to __va_type instead of a pointer to
array[10] of __va_type.
A subtle problem, but I can see that an array is an object type so the
gcc implementation is valid. A shame that __builtin_va_list is
implemented as a magic type so I could not see it was an array.
I should now be able to fix this code.