in reply to XS on 64-bit: Warning from sv_vsetpvf call
Not exactly sure what this "non-conforming" is about... (so I could be wrong), but I think there is no general problem passing around pointers to va_list. It's just that you shouldn't do something like
int printf_handler(const char *format, va_list args) { ... sv_vsetpvf(printf_str, format, &args); ...
with a 64-bit compiler — unless you're using the va_start etc. macros in that same routine, in which case you wouldn't have va_list in its parameter list. OTOH, something like this is fine
int printf_handler(const char *format, va_list* args) { ... sv_vsetpvf(printf_str, format, args); ...
(of course, you'd then have to pass &args to printf_handler()...)
Note that both versions do work fine on 32-bit.
Consider the following example (admittedly somewhat contrived and in pure C only (no Perl/XS involved) — but this helps keep it simple). First the erroneous version:
#include <stdarg.h> #include <stdio.h> #include <errno.h> void vatest__(char* format, va_list* args) { // this kind of represents sv_vsetpvf() char buf[1024]; vsprintf(buf, format, *args); errno = 0; // "Success" perror(buf); } void vatest_(char* format, va_list args) { // this represents your printf_handler() vatest__(format, &args); } void vatest(char* format, ...) { va_list args; va_start (args, format); vatest_(format, args); va_end (args); } int main (int argc, char *argv[]) { char* msg1 = "foo"; char* msg2 = "bar"; vatest("%s: %s", argv[0], msg1); // two args vatest("%s: %s,%s", argv[0], msg1, msg2); // three args return 0; }
___
$ gcc -Wall vatest.c -o vatest vatest.c: In function `vatest_': vatest.c:17: warning: passing arg 2 of `vatest__' from incompatible po +inter type $ ./vatest Segmentation fault $ file vatest vatest: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for G +NU/Linux 2.6.4, dynamically linked (uses shared libs), for GNU/Linux +2.6.4, not stripped
However, if you change the middle two routines as mentioned above
... void vatest_(char* format, va_list* args) { vatest__(format, args); } void vatest(char* format, ...) { va_list args; va_start (args, format); vatest_(format, &args); va_end (args); } ...
things are working fine, even on 64-bit:
$ gcc -Wall vatest.c -o vatest $ ./vatest ./vatest: foo: Success ./vatest: foo,bar: Success
(tested with gcc 3.4.6 on 64-bit SUSE Linux, and with gcc 4.0.4 on a 32-bit Debian box)
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: XS on 64-bit: Warning from sv_vsetpvf call
by songmaster (Beadle) on Jun 27, 2008 at 04:46 UTC | |
by Anonymous Monk on Jun 27, 2008 at 16:35 UTC |