On Jul 22, 2008, at 1:29 AM, Dag Sverre Seljebotn wrote:

> From: Stefan Behnel <[EMAIL PROTECTED]>
> Date: Tuesday, Jul 22, 2008 7:41 am
> Subject: Re: [Cython] Problem with multiple assignment
> To: [EMAIL PROTECTED]: [email protected]
>
> Hi,
>>
>> thanks for the report.

Yes, very interesting.

>>
>> Marc Christiansen wrote:
>> I'm not sure if multiple assignment is the right name, but have a  
>> look
>> at this code:
>>
>> cdef f1():
>>     cdef char a, b
>>
>>     a = b = False
>>
>> Cython 0.9.8 creates this:
>>
>> [...]
>>  *
>>  *     a = b = False             # <<<<<<<<<<<<<<
>>  */
>>   __pyx_1 = __pyx_PyInt_char(Py_False); if (unlikely((__pyx_1 ==  
>> (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0];  
>> __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1;}
>>   __pyx_v_a = __pyx_1;
>>   __pyx_1 = __pyx_PyInt_char(Py_False); if (unlikely((__pyx_1 ==  
>> (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0];  
>> __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1;}
>>   __pyx_v_b = __pyx_1;
>>
>> [...]
>>
>> If I write a = b = 0 (or a = False; b = False), the result is the  
>> expected
>>   __pyx_v_a = 0;
>>   __pyx_v_b = 0;
>>
>> This is not really a problem, more of a missing optimisation for a  
>> case that's handled differently internally. It sounds like it  
>> could go away with Dag's work on the assignment handling anyway. Dag?
>>
>
> The way I visioned it it would turn into
>
> cdef object tmp
> ..
> tmp = False
> a = tmp
> b = tmp

This is in fact exactly what it turns into, though perhaps more  
implicitly then you are thinking of doing, so you are right that some  
special casing may be needed here. However, I think a better  
optimization is that (as has been hinted) True and False start as  
bints, and then get coerced to PyObjects as needed....that was easy.

Now we have

  *     a = b = False             # <<<<<<<<<<<<<<
  *
  */
   __pyx_v_a = 0;
   __pyx_v_b = 0;


as desired. Note that for Python objects

  *     x = False             # <<<<<<<<<<<<<<
  *
  */
   __pyx_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_1))  
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno =  
__LINE__; goto __pyx_L1;}
   Py_DECREF(__pyx_v_x);
   __pyx_v_x = __pyx_1;

Where most of this gets optimized away as

#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True),  
Py_True) : (Py_INCREF(Py_False), Py_False))

(though it perhaps could be made to look prettier).

- Robert



_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to