Menu

#876 SWIG tries to wrap va_list dumbly

None
closed-fixed
nobody
5
2023-03-14
2007-12-04
Loux
No

i use swig from a while now and every thing is fine,
except that i compile now on nocona and the same files don't compile now :(
here is a sample (i cut everything else from .cpp generate from .i:
#include <stdio.h>
void function() {
void *argp4 ;
va_list arg4 ;
if (!argp4) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_psSystemMessage" "', argument " "4"" of type '" "va_list""'");
} else {
va_list * temp = reinterpret_cast< va_list * >(argp4);
arg4 = *temp;
if (SWIG_IsNewObj(res4)) delete temp;
}
}
int main(int argc, char *argv[])
{
function();
return 0;
}
on a x86 this code compile well (gcc-4.1.2)
but on a amd64 this code don't compile :(
i got ISO C++ interdit l'affectation de tableaux
could someone look at that please ?
i'll be glade to give more details if need

Discussion

  • William Fulton

    William Fulton - 2007-12-09

    Logged In: YES
    user_id=242951
    Originator: NO

    Please supply a small standalone interface file showing the problem. Supplying the generated code without the source makes hunting for the bug a guessing game.

     
  • Felipe Sateler Perez

    Logged In: YES
    user_id=876207
    Originator: NO

    I have created a small testcase (copied below, how does one attach things here?).
    This is the result on amd64:

    % swig -c++ -classic -python a.i
    % g++ -c -fPIC a.cpp a_wrap.cxx -I/usr/include/python2.4
    a_wrap.cxx: In function ‘PyObject* _wrap_vararg_vfunction(PyObject*, PyObject*)’:
    a_wrap.cxx:2789: error: invalid array assignment

    --- a.cpp
    #include <stdio.h>
    #include <stdarg.h>

    void vararg_vfunction( int n_args, va_list list) {
    int i;

    for( i = 0; i < n_args; i++ ) {
    printf("%d ", va_arg(list, int) );
    }
    }

    void vararg_function(int n_args, ...) {
    va_list list;
    va_start(list,n_args);
    vararg_vfunction( n_args, list );
    va_end(list);
    }

    --- a.i
    %module a
    %{

    void vararg_function(int n_args, ...);
    void vararg_vfunction(int n_args, va_list list);

    %}

    void vararg_function(int n_args, ...);
    void vararg_vfunction(int n_args, va_list list);

     
  • Olly Betts

    Olly Betts - 2008-01-17
    • labels: --> code generation (general)
     
  • Olly Betts

    Olly Betts - 2008-01-17

    Logged In: YES
    user_id=14972
    Originator: NO

    I don't think this is specific to Python, so marking as "general code gen".

    Wrapping a function taking va_list isn't currently possible with SWIG - see:

    http://www.swig.org/Doc1.3/Varargs.html#Varargs_nn8

    I think the text there is a bit pessimistic though - I think we should be able to automatically generate a C/C++ function with varargs (i.e. ... in the prototype) in place of the va_list which just sets up a va_list and then calls the va_list function. Then we can wrap the automatically generated function instead. But we don't currently do that (and I don't have plans to work on it myself in the foreseeable future).

    For now at least, you should be able to use %extend to write such a wrapper for yourself (and wrap it as the manual explains), and then use %ignore to ignore the va_list version.

    Or if the API being wrapped already has a "..." equivalent, just %ignore the va_list variant.

     
  • Felipe Sateler Perez

    Logged In: YES
    user_id=876207
    Originator: NO

    Note that C99 specifies a va_copy macro that fits exactly this purpose. Don't know what the status of C99 acceptance in compilers, though (or in C++ compilers, for that matter).

     
  • Olly Betts

    Olly Betts - 2008-01-17

    Logged In: YES
    user_id=14972
    Originator: NO

    We don't have a va_list to copy here though, so va_copy is no help. We're converting parameters from the scripting language (Python in your case) to C++, so what we need to do is convert the trailing Python parameters to a va_list. But we can't build a va_list directly - all we can do is to specify what the "..." can be (as the manual describes), and essentially generate wrappers for this set of overloaded functions.

    The current generated code you are getting is just wrong - it's SWIG's generic parameter conversion, applied to va_list. Even if that compiles, it isn't going to work (at least not in a useful way).

     
  • Olly Betts

    Olly Betts - 2008-07-04
    • summary: amd64: .cpp generate file don't compile --> SWIG tries to wrap va_list dumbly
     
  • Olly Betts

    Olly Betts - 2008-07-04

    Logged In: YES
    user_id=14972
    Originator: NO

    Retitling to describe the actual problem.

     
  • Olly Betts

    Olly Betts - 2022-01-27

    The documentation now describes how to wrap these by providing a function with ... which forwards to the va_list and wrapping that instead:

    commit 8be65ec8e7d571a67715129298cfb9871232fd6f
    Author: William S Fulton <wsf@fultondesigns.co.uk>
    Date:   Fri Dec 7 07:38:24 2012 +0000
    
        Add in va_list varargs workaround suggested by Antoine Mathys
    
        git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13949 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    

    I think it would be feasible to generate that forwarding code automatically or semi-automatically, so I guess this should stay open.

     
  • Olly Betts

    Olly Betts - 2023-03-14
    • status: open --> closed-fixed
    • Group: -->
     
  • Olly Betts

    Olly Betts - 2023-03-14

    Reflecting on this, I think the now-documented approach mentioned above is a reasonable solution.

    Also APIs I've seen which have a function taking va_list often also provide a corresponding varargs function too, and in such cases attempting to automatically wrap the va_list one by generating a varargs function and wrapping it would be actively unhelpful.

    It'd be nicer to not generate wrapper code which doesn't compile for functions taking va_list, but I don't think we have a way to avoid wrapping a function based on the type of a parameter. We could perhaps add dummy typemaps for va_list so we generate compilable code, but the compile error does flag up that there's something to do about the va_list function.

    So closing, but if anyone has better ideas please reopen.

     

Log in to post a comment.