Hi,
With the SWIG below, I get a compile failure: it looks like SWIG_fail is expanding to "goto fail", but the "fail:" label is in the wrong function (the calling function).
This is with swig 2.0.9, and my target is python, though I think the problem is language-independent.
%module test %include <exception.i> %inline %{ typedef struct { } s; %} %extend s { s(int x) { // option A SWIG_exception(SWIG_RuntimeError, "Msg"); // option B PyErr_SetString(PyExc_RuntimeError, "Msg"); SWIG_fail; return NULL; } }
Produces:
#define SWIG_fail goto fail // [snip] SWIGINTERN s *new_s(int x){ SWIG_exception(SWIG_RuntimeError, "Msg"); PyErr_SetString(PyExc_RuntimeError, "Msg"); SWIG_fail; return NULL; } SWIGINTERN PyObject *_wrap_new_s(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { /// [snip] result = (s *)new_s(arg1); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_s, SWIG_POINTER_NEW | 0 ); return resultobj; fail: return NULL; }
Notice that 'SWIG_fail', ie, 'goto fail' is in 'new_s()', but the 'fail:' label is in '_wrap_new_s'.
Thanks,
dustin
Still the case with git master.
You can probably workaround by adding a
fail:
label before thereturn NULL;
in your%extend
constructor. With-builtin
it looks like that would work; without-builtin
I'm not so sure.Looking at the SWIG manual they don't seem to describe
SWIG_fail
in a common place, but where target-language-specific docs describe what it's for they always seem to say things like (this particular quote is from Python.html):I've added emphasis - my point here is that use in
%extend
isn't within such a context soSWIG_fail
shouldn't be expected to work there.So how should one raise a target language exception from a
%extend
method?I suppose
%extend
effectively adds a method to the C++ class and then wraps it for SWIG, so this is best done in the same way you'd raise a target language exception from a method actually in the wrapped API - i.e. you throw a C++ exception from the%extend
which is then caught using a%exception
block which doesSWIG_exception(SWIG_RuntimeError, "Msg"); SWIG_fail;
or similar.I don't really see how else this could be solved without SWIG inlining the
%extend
code into the wrapper function, which seems likely to cause other problems (for example, clashes between variables in the wrapper function and those in the%extend
function). AlsoSWIG.html
currently explicitly notes:So I think the best resolution here is to explicitly clarify that
SWIG_fail
isn't for use in%extend
. ReallyTypemaps.html
ought to documentSWIG_fail
instead of leaving it to the target-language-specific docs -Typemaps.html
already has many examples using it so that seems a good place to document it, and then we can add the note about%extend
there.