diff options
author | Philipp Wagner <mail@philipp-wagner.com> | 2023-05-15 20:51:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-15 20:51:07 +0200 |
commit | f797c86c31f4bceabb386278f0d1686cb218da9b (patch) | |
tree | 1504bb2ed9d9a2ae81007d1939129915e406a34e | |
parent | 663c924462adec202c9f469fa346bda1b2264dfa (diff) | |
download | cython-f797c86c31f4bceabb386278f0d1686cb218da9b.tar.gz |
Fix a signedness compiler warning in vector.to_py (GH-5438)
When compiling cythonized code which uses `std::vector` we get the
following compiler warning on GCC 8 and Python 3.9 (which is turned into
an error in our case):
```
my_file.cpp: In function ‘PyObject* __pyx_convert_vector_to_py_int(const std::vector<int>&)’:
my_file.cpp:4716:33: warning: comparison of integer expressions of different signedness: ‘Py_ssize_t’ {aka ‘long int’} and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
~~~~~~~~~~^~~~~~~~~~~
```
The generated code in question is as follows:
```
/* "vector.to_py":75
* cdef object item
*
* for i in range(v.size()): # <<<<<<<<<<<<<<
* item = v[i]
* Py_INCREF(item)
*/
__pyx_t_3 = __pyx_v_v.size();
__pyx_t_4 = __pyx_t_3;
for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
__pyx_v_i = __pyx_t_5;
```
`__pyx_t_5` is of type `‘Py_ssize_t’` (signed), and `__pyx_t_4` aka
`__pyx_t_3` is `size_t` (unsigned), causing GCC to rightfully complain.
Fix the generated code by explicitly using the signed variant of the
vector's size in the loop.
This bug has been introduced in
https://github.com/cython/cython/pull/4081, which also contains some
discussion on the use of signed vs unsigned types. This patch chooses to
keep the status quo and only fixes the compiler warning.
-rw-r--r-- | Cython/Utility/CppConvert.pyx | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/Cython/Utility/CppConvert.pyx b/Cython/Utility/CppConvert.pyx index 35f4c50ef..1c6239b2b 100644 --- a/Cython/Utility/CppConvert.pyx +++ b/Cython/Utility/CppConvert.pyx @@ -66,13 +66,14 @@ cdef extern from "Python.h": cdef object {{cname}}(const vector[X]& v): if v.size() > <size_t> PY_SSIZE_T_MAX: raise MemoryError() + v_size_signed = <Py_ssize_t> v.size() - o = PyList_New(<Py_ssize_t> v.size()) + o = PyList_New(v_size_signed) cdef Py_ssize_t i cdef object item - for i in range(v.size()): + for i in range(v_size_signed): item = v[i] Py_INCREF(item) PyList_SET_ITEM(o, i, item) |