|Do you know where your variables are?|
XS on 64-bit: Warning from sv_vsetpvf callby songmaster (Sexton)
|on Jun 26, 2008 at 20:29 UTC||Need Help??|
songmaster has asked for the
wisdom of the Perl Monks concerning the following question:
I'm working on an XS interface to an external C library. My current code builds and works fine on 32-bit x86 Linux (Fedora Core 8, Perl 5.8.8) and on Solaris 10, but when I build it for 64-bit Linux (FC8 on x86_64) I get this compiler warning and the program segfaults when this routine is called:
The relevant lines of Cap5.xs are:
Line 1013 is the last one shown above.
Perl's proto.h file declares Perl_sv_vsetpvf as:
The final argument there is a va_list*, which is exactly what my code is giving it. I'm not sure it really should have been a va_list* given that vprintf et al. take a va_list, but that's what the header says and it works fine on the other systems.
Interestingly, if I drop the & and just pass args as the final argument the code seems to work fine on 64-bit Linux (although the compiler still warns), but then it segfaults on the other systems.
Update: It appears that taking the address of a va_list is non-conforming C,
2nd Update: On amd64 (and apparently on PowerPC too) va_list is defined by the ABI as an array:
Thus within printf_handler() the args variable is already a pointer to the structure. This explains why dropping the & works as I described in my original question. Unfortunately that's no use on other architectures though.
Using va_copy() (or its equivalent) to copy args into an auto variable allows me to take the address of the copy and pass that pointer into sv_vsetpvf().