[Cython] CF and finally clause

Stefan Behnel stefan_ml at behnel.de
Tue May 24 23:04:28 CEST 2011


Robert Bradshaw, 24.05.2011 22:07:
> On Tue, May 24, 2011 at 12:33 PM, Vitja Makarov wrote:
>> When I create control flow graph I have to visit finally clause twice.
>> This is required because of different outputs should be generated for
>> success and exception case:
>>
>> try:
>>     a = might_raise()
>> finally:
>>     pass # 'a' might be uninitialized here
>> print(a)  # and definitely defined here
>>
>> So after tracking both cases I have to merge states back because same
>> code is generated for each.

Note that there are also the break, continue and return cases.


>> Maybe it's a good idea to split success/exception case by copying it
>> at PostParse transform?
>
> -1
>
> I don't see any difference compared to merging the states from
>
> if b:
>      a = None
> else:
>      # don't assign to a

The difference is that try-finally executes the exact same code in both 
cases, but both cases are otherwise in completely distinct code paths. In a 
way, it's the opposite of your example, where the same outer code path can 
execute either of the distinct inner code sections.

I'm not so opposed to this proposal. I have been (idly and unfoundedly) 
wondering basically forever if the current way try-finally is implemented 
is actually a good one. I can accept a performance penalty for the 
exception case in both try-finally and try-except, but the normal case in 
try-finally should run as fast as possible. I'm not sure the C compiler can 
always detect what that "normal" case is in order to properly optimise for it.

However, given that there are actually up to four normal cases and only one 
exception case, I also wonder if even Cython can detect what the "normal" 
case should be, and if it's really worth providing a distinct 
implementation in order to optimise it.

Stefan


More information about the cython-devel mailing list