12

Please explain what are these warning by SWIG and how to avoid it?

Warning 503: Can't wrap 'operator ()' unless renamed to a valid identifier.
Warning 503: Can't wrap 'operator =' unless renamed to a valid identifier.
Warning 503: Can't wrap 'operator *' unless renamed to a valid identifier.

The warnings are generated when SWIG generated C++ code is compiled under Android NDK.

arsalank2
  • 1,683
  • 1
  • 16
  • 25

3 Answers3

15

Java doesn't have an equivalent of operator() or operator= in the same sense as C++, so there's no way for SWIG to directly wrap it. Because they might be important you're shown a warning that explains they're not being wrapped. (Missing operator= might be particularly bad sometimes).

This code exhibits such a warning when running swig -Wall -c++ -java:

%module Sample

struct test {
  bool operator()();
};

But you can silence the warning and tell SWIG to expose the operator directly as a regular member function by saying something like:

%module Sample

%rename(something_else) operator();

struct test {
  bool operator()();
};

Which results in a function called something_else being added in place of operator() in the generated wrapper.

Or you can assert to SWIG that ignoring those is just fine using:

%ignore operator()

(You can also apply either of those directives less broadly by qualifying the operators with the class names).

Flexo
  • 87,323
  • 22
  • 191
  • 272
3

You need to handle overloaded operators in a special way in SWIG, if you want to use them in the target language. See here.

pmr
  • 58,701
  • 10
  • 113
  • 156
1

You can run into this warning if you have a %rename directive that appears before a %template directive for instantiating a function like so:

%module some_module
%rename("%(undercase)s", %$isfunction) ""; 
// equivalently  %rename("%(utitle)s", %$isfunction) "";

%inline %{
template<class T>
void MyFunction(){}
%}
// ...

%template(MyIntFunction) MyFunction<int>;

warning 503: Can't wrap 'my_function< int >' unless renamed to a valid identifier

And you cannot try to anticipate the rename in your %template:

%template(MyIntFunction) my_function<int>;

Because then you'll get

error : Template 'myfunction' undefined.

Which is very frustrating if you're applying global renaming rules, and you really only need to "ignore renaming" for just a few things. Unlike typemaps, rename directives live for all-time. It'd be nice to be able to turn them off, even temporarily.

The only workaround for this I've come up with is to go back to the %rename and update it to explicitly only match (or rather, not match) the template functions you've declared inline. Like so:

// don't rename functions starting with "MyFunction"
%rename("%(undercase)s", %$isfunction, notregexmatch$name="^MyFunction") "";

It's not perfect, but it's a workaround.

(This was all done in SWIG 4.0)

AndyG
  • 39,700
  • 8
  • 109
  • 143