Fixing gcc warnings when -pedantic is used

Fixing warnings related to casting object pointer to function pointer
and back. Apparently `void*` and `void(*)()` are not the same size on
some weird architectures and gcc complains when casting between the two
when using -pedantic flag.

Work around is to go via uintptr_t. I added helper methods to `cast.h`
and used them in `pybind11.h` and in `numpy.h`. I only tested compilation
with gcc on Linux, but it should be portable to any c++11 compiler.
This commit is contained in:
Kirill Kouzoubov 2016-03-22 20:39:41 +11:00
parent 84ec78feeb
commit ed50e70f8c
3 changed files with 21 additions and 7 deletions

View File

@ -34,6 +34,20 @@ private:
NAMESPACE_BEGIN(detail)
/// Convert from any type pointer to another avoding warnings about void* vs (void*()) incompatibility.
template<typename A, typename B>
A cast_any_ptr(B x) { return reinterpret_cast<A>(reinterpret_cast<uintptr_t>(x)); }
/// Return (*)(Args...) -> void*
template <typename Return, typename... Args>
void * func_to_voidp(Return (*f)(Args...)) { return cast_any_ptr<void*>(f); }
/// void* -> Return (*)(Args...)
template <typename Return, typename... Args>
Return (*voidp_to_func(void * f))(Args...) { return cast_any_ptr<Return (*)(Args...)>(f); }
/// Additional type information which does not fit into the PyTypeObject
struct type_info {
PyTypeObject *type;

View File

@ -56,11 +56,11 @@ public:
void **api_ptr = (void **) (c ? PyCObject_AsVoidPtr(c.ptr()) : nullptr);
#endif
API api;
api.PyArray_Type_ = (decltype(api.PyArray_Type_)) api_ptr[API_PyArray_Type];
api.PyArray_DescrFromType_ = (decltype(api.PyArray_DescrFromType_)) api_ptr[API_PyArray_DescrFromType];
api.PyArray_FromAny_ = (decltype(api.PyArray_FromAny_)) api_ptr[API_PyArray_FromAny];
api.PyArray_NewCopy_ = (decltype(api.PyArray_NewCopy_)) api_ptr[API_PyArray_NewCopy];
api.PyArray_NewFromDescr_ = (decltype(api.PyArray_NewFromDescr_)) api_ptr[API_PyArray_NewFromDescr];
api.PyArray_Type_ = detail::cast_any_ptr<decltype(api.PyArray_Type_)> (api_ptr[API_PyArray_Type]);
api.PyArray_DescrFromType_ = detail::cast_any_ptr<decltype(api.PyArray_DescrFromType_)> (api_ptr[API_PyArray_DescrFromType]);
api.PyArray_FromAny_ = detail::cast_any_ptr<decltype(api.PyArray_FromAny_)> (api_ptr[API_PyArray_FromAny]);
api.PyArray_NewCopy_ = detail::cast_any_ptr<decltype(api.PyArray_NewCopy_)> (api_ptr[API_PyArray_NewCopy]);
api.PyArray_NewFromDescr_ = detail::cast_any_ptr<decltype(api.PyArray_NewFromDescr_)> (api_ptr[API_PyArray_NewFromDescr]);
return api;
}

View File

@ -49,7 +49,7 @@ public:
template <typename Return, typename... Args, typename... Extra>
cpp_function(Return (*f)(Args...), const Extra&... extra) {
auto rec = new detail::function_record();
rec->data = (void *) f;
rec->data = detail::func_to_voidp(f);
typedef arg_value_caster<Args...> cast_in;
typedef return_value_caster<Return> cast_out;
@ -67,7 +67,7 @@ public:
/* Do the call and convert the return value back into the Python domain */
handle result = cast_out::cast(
args.template call<Return>((Return (*) (Args...)) rec->data),
args.template call<Return>(detail::voidp_to_func<Return,Args...>(rec->data)),
rec->policy, parent);
/* Invoke call policy post-call hook */