Unreachable code when using cython.inline
<p>I'm using Cython to compile a function to C, but get a "Unreachable code" warning. When I inspect the <code>pyx</code> file, I see an additional <code>return locals()</code> which I don't quite understand how it got there.</p>

<p>The code is generated by <code>cython.inline</code>:</p>

<pre><code>cython.inline('return a * b + c if a &gt; b else 0.0', a=1, b=2, c=3)
</code></pre>

<p>which produces a pyx file that looks like this:</p>

<pre><code>def __invoke(double a, double b, double c):
    return a * b + c if a &gt; b^2 else 0.0
    return locals()
</code></pre>

<p>The reason I am cythonizing this function is to improve performance. The above function is a simplification, but the basic elements are the same. Note that the inline function is not using <code>numpy</code> arrays. If anyone can think of a faster way to evaluate the expression, I am happy to try it out (the syntax for the original expression is a bit different, but I can compile it to any format).</p>

<p>Anyway, the main point of this question is to understand why and additional <code>return</code> statement has been added and how to remove it.</p>

<p><strong>Update</strong></p>

<p>This is the overhead I've noticed from the <code>cython.inline</code> calls (refers to conversation with @DavidW).</p>

<p><a href="http://i.stack.imgur.com/rQxIA.png" rel="nofollow"><img src="http://i.stack.imgur.com/rQxIA.png" alt="enter image description here"></a></p>

<p>I think it's so that if you don't add a return statement you get back a dictionary of local variables. E.g.</p>

<pre><code>cython.inline('''x = a*b
y = b+c
z = a-c
''', a=1, b=2, c=3)
</code></pre>

<p>will give you back a dictionary of <code>x</code>, <code>y</code>, and <code>z</code>. Obviously it's a bit unnecessary since you could do that manually yourself, but it makes some use-cases easy (and would break compatibility with existing code if removed).</p>

<p>Cython accomplishes those features by adding <code>return locals()</code> to the end of everything it compiles. You can find it in the <a href="https://github.com/cython/cython/blob/499d262250f7f4d8f392bb2165a2692937d1c4fa/Cython/Build/Inline.py#L216" rel="nofollow">source code</a>.</p>

<p>I don't think you can get rid of it, but it also costs you nothing (except a compiler warning) - it's obvious to the C compiler that the code is unreachable so it never gets generated.</p>

<hr>

<p>To answer your secondary question about improving performance - this kind of calculation presumably only matters if it's called repeatedly? I'd try to get the loop in Cython too if at all possible, otherwise I'd be surprised if you gained much.</p>

python cython