spence
spence

Reputation: 67

invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]; VTK-7.1.1 compilation error

As the title says, I'm not a c++ programmer, I'm just trying to compile this so I can compile some modules for FreeCAD that I would like. I had problems with VTK-8.90 I couldn't figure out so I'm trying this version because it is the recommended stable version for the modules. Not being a programmer and googling this error a bunch, I played around a lot with removing and adding/removing various "const" and "char*" to the indicated errors- but I really don't know what I'm doing so I thought I'd try to get a specific answer. (I don't think the source code as written is necessarily the problem.) I'm compiling to use it with python3.7, the default is 2.7, but this shouldn't matter right because this is c++ code?

This is the error specifically:

[ 98%] Building CXX object Wrapping/PythonCore/CMakeFiles/vtkWrappingPythonCore.dir/vtkPythonArgs.cxx.o
/src/VTK-7.1.1/Wrapping/PythonCore/vtkPythonArgs.cxx: In instantiation of ‘bool vtkPythonGetStringValue(PyObject*, T*&, const char*) [with T = char; PyObject = _object]’:
/src/VTK-7.1.1/Wrapping/PythonCore/vtkPythonArgs.cxx:287:66:   required from here
/src/VTK-7.1.1/Wrapping/PythonCore/vtkPythonArgs.cxx:105:25: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
     a = PyUnicode_AsUTF8(o);
         ~~~~~~~~~~~~~~~~^~~
make[2]: *** [Wrapping/PythonCore/CMakeFiles/vtkWrappingPythonCore.dir/build.make:63: Wrapping/PythonCore/CMakeFiles/vtkWrappingPythonCore.dir/vtkPythonArgs.cxx.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:9917: Wrapping/PythonCore/CMakeFiles/vtkWrappingPythonCore.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

And this is the first referenced section of vtkPythonArgs.cxx (starting from line 93):

template <class T> inline
bool vtkPythonGetStringValue(PyObject *o, T *&a, const char *exctext)
{
  if (PyBytes_Check(o))
  {
    a = PyBytes_AS_STRING(o);
    return true;
  }
#ifdef Py_USING_UNICODE
  else if (PyUnicode_Check(o))
  {
#if PY_VERSION_HEX >= 0x03030000
    a = PyUnicode_AsUTF8(o);
    return true;
#else
    PyObject *s = _PyUnicode_AsDefaultEncodedString(o, NULL);
    if (s)
    {
      a = PyBytes_AS_STRING(s);
      return true;
    }

    exctext = "(unicode conversion error)";
#endif
  }
#endif

  PyErr_SetString(PyExc_TypeError, exctext);
  return false;
}

inline bool vtkPythonGetStdStringValue(PyObject *o, std::string &a, const char *exctext)
{
  if (PyBytes_Check(o))
  {
    char* val;
    Py_ssize_t len;
    PyBytes_AsStringAndSize(o, &val, &len);
    a = std::string(val, len);
    return true;
  }
#ifdef Py_USING_UNICODE
  else if (PyUnicode_Check(o))
  {
#if PY_VERSION_HEX >= 0x03030000
    Py_ssize_t len;
    const char* val = PyUnicode_AsUTF8AndSize(o, &len);
    a = std::string(val, len);
    return true;
#else
    PyObject *s = _PyUnicode_AsDefaultEncodedString(o, NULL);
    if (s)
    {
      char* val;
      Py_ssize_t len;
      PyBytes_AsStringAndSize(s, &val, &len);
      a = std::string(val, len);
      return true;
    }

    exctext = "(unicode conversion error)";
#endif
  }
#endif

  PyErr_SetString(PyExc_TypeError, exctext);
  return false;
}

Line 287 (starting from 281):

inline
bool vtkPythonGetValue(PyObject *o, char *&a)
{
  a = NULL;

  return (o == Py_None ||
          vtkPythonGetStringValue(o, a, "string or None required"));
}

The file is 1600 lines, I'm not sure if the whole thing would be more help.

Thanks.

Upvotes: 0

Views: 756

Answers (1)

Mike
Mike

Reputation: 67

Well, it looks like the function PyUnicode_AsUTF8 must be returning a char const*. The function vtkPythonGetValue calls the template function vtkPythonGetStringValue. vtkPythonGetValue takes as parameter a, an lvalue reference to non-const pointer to non-const char and passes it along to vtkPythonGetStringValue, causing it to get instantiated with T deduced to char instead of char const. A pointer to const object cannot be assigned to a pointer to non-const, only the reverse is allowed. So the function vtkPythonGetValue should really be taking an lvalue reference to non-const pointer to const char. Like so:

inline
bool vtkPythonGetValue(PyObject* o, char const*& a)
{
  a = NULL;
  return (o == Py_None ||
          vtkPythonGetStringValue(o, a, "string or None required"));
}

Upvotes: 1

Related Questions