mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Avoid C-style const casts (#659)
* Avoid C-style const casts Replace C-style casts that discard `const` with `const_cast` (and, where necessary, `reinterpret_cast` as well). * Warn about C-style const-discarding casts Change pybind11_enable_warnings to also enable `-Wcast-qual` (warn if a C-style cast discards `const`) by default. The previous commit should have gotten rid of all of these (at least, all the ones that tripped in my build, which included the tests), and this should discourage more from newly appearing.
This commit is contained in:
parent
d534bd670e
commit
e15fa9f99a
@ -40,7 +40,7 @@ function(pybind11_enable_warnings target_name)
|
|||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${target_name} PRIVATE /W4)
|
target_compile_options(${target_name} PRIVATE /W4)
|
||||||
else()
|
else()
|
||||||
target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion)
|
target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion -Wcast-qual)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(PYBIND11_WERROR)
|
if(PYBIND11_WERROR)
|
||||||
|
@ -422,7 +422,7 @@ protected:
|
|||||||
template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) {
|
template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) {
|
||||||
return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; }
|
return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; }
|
||||||
template <typename T = type> static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) {
|
template <typename T = type> static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) {
|
||||||
return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *) arg))); }; }
|
return [](const void *arg) -> void * { return (void *) new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg)))); }; }
|
||||||
#else
|
#else
|
||||||
/* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations.
|
/* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations.
|
||||||
Use a workaround that only tests for constructibility for now. */
|
Use a workaround that only tests for constructibility for now. */
|
||||||
@ -706,7 +706,7 @@ public:
|
|||||||
return PyUnicode_DecodeLatin1(str, 1, nullptr);
|
return PyUnicode_DecodeLatin1(str, 1, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator char*() { return success ? (char *) value.c_str() : nullptr; }
|
operator char*() { return success ? const_cast<char *>(value.c_str()) : nullptr; }
|
||||||
operator char&() { return value[0]; }
|
operator char&() { return value[0]; }
|
||||||
|
|
||||||
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
|
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
|
||||||
@ -729,7 +729,7 @@ public:
|
|||||||
return PyUnicode_FromWideChar(wstr, 1);
|
return PyUnicode_FromWideChar(wstr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator wchar_t*() { return success ? (wchar_t *) value.c_str() : nullptr; }
|
operator wchar_t*() { return success ? const_cast<wchar_t *>(value.c_str()) : nullptr; }
|
||||||
operator wchar_t&() { return value[0]; }
|
operator wchar_t&() { return value[0]; }
|
||||||
|
|
||||||
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
|
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
|
||||||
|
@ -357,8 +357,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(
|
auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(
|
||||||
api.PyArray_Type_, descr.release().ptr(), (int) ndim, (Py_intptr_t *) shape.data(),
|
api.PyArray_Type_, descr.release().ptr(), (int) ndim,
|
||||||
(Py_intptr_t *) strides.data(), const_cast<void *>(ptr), flags, nullptr));
|
reinterpret_cast<Py_intptr_t *>(const_cast<size_t*>(shape.data())),
|
||||||
|
reinterpret_cast<Py_intptr_t *>(const_cast<size_t*>(strides.data())),
|
||||||
|
const_cast<void *>(ptr), flags, nullptr));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
pybind11_fail("NumPy: unable to create array!");
|
pybind11_fail("NumPy: unable to create array!");
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
@ -382,7 +384,7 @@ public:
|
|||||||
template<typename T> array(const std::vector<size_t>& shape,
|
template<typename T> array(const std::vector<size_t>& shape,
|
||||||
const std::vector<size_t>& strides,
|
const std::vector<size_t>& strides,
|
||||||
const T* ptr, handle base = handle())
|
const T* ptr, handle base = handle())
|
||||||
: array(pybind11::dtype::of<T>(), shape, strides, (void *) ptr, base) { }
|
: array(pybind11::dtype::of<T>(), shape, strides, (const void *) ptr, base) { }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
array(const std::vector<size_t> &shape, const T *ptr,
|
array(const std::vector<size_t> &shape, const T *ptr,
|
||||||
|
@ -129,8 +129,9 @@ protected:
|
|||||||
detail::process_attributes<Extra...>::precall(call);
|
detail::process_attributes<Extra...>::precall(call);
|
||||||
|
|
||||||
/* Get a pointer to the capture object */
|
/* Get a pointer to the capture object */
|
||||||
capture *cap = (capture *) (sizeof(capture) <= sizeof(call.func.data)
|
auto data = (sizeof(capture) <= sizeof(call.func.data)
|
||||||
? &call.func.data : call.func.data[0]);
|
? &call.func.data : call.func.data[0]);
|
||||||
|
capture *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));
|
||||||
|
|
||||||
/* Override policy for rvalues -- always move */
|
/* Override policy for rvalues -- always move */
|
||||||
constexpr auto is_rvalue = !std::is_pointer<Return>::value
|
constexpr auto is_rvalue = !std::is_pointer<Return>::value
|
||||||
@ -167,7 +168,7 @@ protected:
|
|||||||
sizeof(capture) == sizeof(void *);
|
sizeof(capture) == sizeof(void *);
|
||||||
if (is_function_ptr) {
|
if (is_function_ptr) {
|
||||||
rec->is_stateless = true;
|
rec->is_stateless = true;
|
||||||
rec->data[1] = (void *) &typeid(FunctionType);
|
rec->data[1] = const_cast<void *>(reinterpret_cast<const void *>(&typeid(FunctionType)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +346,7 @@ protected:
|
|||||||
/* Install docstring */
|
/* Install docstring */
|
||||||
PyCFunctionObject *func = (PyCFunctionObject *) m_ptr;
|
PyCFunctionObject *func = (PyCFunctionObject *) m_ptr;
|
||||||
if (func->m_ml->ml_doc)
|
if (func->m_ml->ml_doc)
|
||||||
std::free((char *) func->m_ml->ml_doc);
|
std::free(const_cast<char *>(func->m_ml->ml_doc));
|
||||||
func->m_ml->ml_doc = strdup(signatures.c_str());
|
func->m_ml->ml_doc = strdup(signatures.c_str());
|
||||||
|
|
||||||
if (rec->is_method) {
|
if (rec->is_method) {
|
||||||
@ -366,12 +367,12 @@ protected:
|
|||||||
std::free((char *) rec->doc);
|
std::free((char *) rec->doc);
|
||||||
std::free((char *) rec->signature);
|
std::free((char *) rec->signature);
|
||||||
for (auto &arg: rec->args) {
|
for (auto &arg: rec->args) {
|
||||||
std::free((char *) arg.name);
|
std::free(const_cast<char *>(arg.name));
|
||||||
std::free((char *) arg.descr);
|
std::free(const_cast<char *>(arg.descr));
|
||||||
arg.value.dec_ref();
|
arg.value.dec_ref();
|
||||||
}
|
}
|
||||||
if (rec->def) {
|
if (rec->def) {
|
||||||
std::free((char *) rec->def->ml_doc);
|
std::free(const_cast<char *>(rec->def->ml_doc));
|
||||||
delete rec->def;
|
delete rec->def;
|
||||||
}
|
}
|
||||||
delete rec;
|
delete rec;
|
||||||
@ -1666,7 +1667,7 @@ public:
|
|||||||
exception(handle scope, const char *name, PyObject *base = PyExc_Exception) {
|
exception(handle scope, const char *name, PyObject *base = PyExc_Exception) {
|
||||||
std::string full_name = scope.attr("__name__").cast<std::string>() +
|
std::string full_name = scope.attr("__name__").cast<std::string>() +
|
||||||
std::string(".") + name;
|
std::string(".") + name;
|
||||||
m_ptr = PyErr_NewException((char *) full_name.c_str(), base, NULL);
|
m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base, NULL);
|
||||||
if (hasattr(scope, name))
|
if (hasattr(scope, name))
|
||||||
pybind11_fail("Error during initialization: multiple incompatible "
|
pybind11_fail("Error during initialization: multiple incompatible "
|
||||||
"definitions with name \"" + std::string(name) + "\"");
|
"definitions with name \"" + std::string(name) + "\"");
|
||||||
|
Loading…
Reference in New Issue
Block a user