Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ division operator overloading unwanted cast #1950

Closed
10se1ucgo opened this issue Oct 26, 2017 · 2 comments
Closed

C++ division operator overloading unwanted cast #1950

10se1ucgo opened this issue Oct 26, 2017 · 2 comments

Comments

@10se1ucgo
Copy link

When wrapping a class like so

# vec3.pxd
cdef extern from "math3d_c.h":
    cdef cppclass Vector3[T]:
        T x, y, z
        Vector3() except +
        Vector3(T x, T y, T z) except +

        Vector3[T] operator*(T &b)
        Vector3[T] operator/(T &b)
# math3d.pyx
from . cimport vec3

cdef class Vector3:
    cdef vec3.Vector3[double] c_vec

    def __init__(self, double x=0, double y=0, double z=0):
        self.c_vec.x = x
        self.c_vec.y = y
        self.c_vec.z = z

    def __mul__(Vector3 a, double scalar):
        return new_vector3_from(a.c_vec * scalar)

    def __truediv__(Vector3 a, double scalar):
        if scalar == 0:
            raise ZeroDivisionError("Vector3 division by zero")
        return new_vector3_from(a.c_vec / scalar)

# new_vector3_from just constructs a Python Vector3 object from a C++ Vector3 object, unrelated

The code generated by Cython for __mul__ is correct, however for __truediv__, Cython unnecessarily casts scalar to a Vector3.

// mul
 __pyx_t_1 = ((PyObject *)__pyx_f_6extlib_6math3d_new_vector3_from((__pyx_v_a->c_vec * __pyx_v_scalar))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error)

// truediv
__pyx_t_2 = ((PyObject *)__pyx_f_6extlib_6math3d_new_vector3_from((__pyx_v_a->c_vec / ((Vector3<double> )__pyx_v_scalar)))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)

Which, of course, causes an error if the wrapped class doesn't provide an overload for that method.

@10se1ucgo 10se1ucgo changed the title __truediv__ unwanted cast C++ division operator overloading unwanted cast Oct 26, 2017
@scoder
Copy link
Contributor

scoder commented Oct 27, 2017

That looks wrong. Might be a problem with the code that tries to find a common floatish type for true division.

Please also see
http://docs.cython.org/en/latest/src/userguide/special_methods.html#arithmetic-operators

@tcdude
Copy link

tcdude commented May 26, 2019

I encountered the same behavior. All other arithmetic operators I used in my code work as expected, only overloading __truediv__() somehow leads to this unwanted cast.

I'm happy to provide more detailed information if necessary to help track the problem down, but the original text pretty much sums up the unwanted behavior.

robertwb added a commit that referenced this issue May 27, 2019
robertwb added a commit that referenced this issue May 27, 2019
@scoder scoder added the C++ label May 28, 2019
@scoder scoder added this to the 0.29.9 milestone May 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants