Stefan Behnel, 27.01.2011 09:40:
> Robert Bradshaw, 27.01.2011 07:39:
>> On Wed, Jan 26, 2011 at 10:29 PM, Stefan Behnel wrote:
>>> there is this code in Sage (wrapper_rr.pyx/.pxd):
>>>
>>>     cdef class Wrapper_rr(Wrapper):
>>>         cdef int _n_args
>>>         cdef mpfr_t* _args
>>>         ...
>>>
>>>     # offending line:
>>>     mpfr_init2(self._args[i], self.domain.prec())
>>>
>>> The signature of mpfr_init2() is
>>>
>>>       ctypedef __mpfr_struct* mpfr_t
>>>       void mpfr_init2 (mpfr_t x, mp_prec_t prec)
>>>  [...]
>>>     sage/ext/interpreters/wrapper_rr.c:2737: error: incompatible types in
>>> assignment
>>>
>>> Any idea what might be going wrong here?
>>
>> mpfr_t is actually an __mpfr_struct[1]. (It's a clever hack to have
>> stack-allocated, pass-by-reference semantics.) We only need to pull
>> non-simple arguments into temp variables.
>
> Ah, that would explain it. But this also means that there may be cases
> where we can't help breaking existing code with such a change.

Ok, this particular code really can't be worked around by Cython. From the 
POV of the compiler, the second function argument (a Python function call 
result) may potentially have side effects on the first one, so both must be 
coerced to a temp in the right order to be correct.

  2732     /* "sage/ext/interpreters/wrapper_rr.pyx":56
  2733  *         if self._args == NULL: raise MemoryError
  2734  *         for i in range(count):
  2735  *             mpfr_init2(self._args[i], self.domain.prec()) # <<<<<
  2736  *         val = args['constants']
  2737  *         self._n_constants = len(val)
  2738  */

  2739     __pyx_t_8 = (((struct 
__pyx_obj_4sage_3ext_12interpreters_10wrapper_rr_Wrapper_rr 
*)__pyx_v_self)->_args[__pyx_v_i]);

  2740     __pyx_t_2 = PyObject_GetAttr(((PyObject *)((struct 
__pyx_obj_4sage_3ext_12interpreters_10wrapper_rr_Wrapper_rr 
*)__pyx_v_self)->domain), __pyx_n_s__prec); if /*...*/

  2741     __Pyx_GOTREF(__pyx_t_2);
  2742     __pyx_t_3 = PyObject_Call(__pyx_t_2, ((PyObject 
*)__pyx_empty_tuple), NULL); if /*...*/

  2743     __Pyx_GOTREF(__pyx_t_3);
  2744     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  2745     __pyx_t_9 = __Pyx_PyInt_from_py_mp_prec_t(__pyx_t_3); if /*...*/
  2746     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  2747     mpfr_init2(__pyx_t_8, __pyx_t_9);


And given that Cython cannot know that the pointer is actually not a 
pointer, it generates the expected code here which only the C compiler can 
detect as invalid.

This needs fixing in Sage in one way or another.

Stefan
_______________________________________________
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to