Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It is <em>certain</em> that at least one C++ compiler will recognize the situation (when the 0 is known at compile time) and make it a no-op:</p> <p><strong>Source</strong></p> <pre><code>inline int shift( int what, int bitcount) { return what &gt;&gt; bitcount ; } int f() { return shift(42,0); } </code></pre> <p><strong>Compiler switches</strong></p> <pre><code>icpc -S -O3 -mssse3 -fp-model fast=2 bitsh.C </code></pre> <p><strong>Intel C++ 11.0 assembly</strong></p> <pre><code># -- Begin _Z1fv # mark_begin; .align 16,0x90 .globl _Z1fv _Z1fv: ..B1.1: # Preds ..B1.0 movl $42, %eax #7.10 ret #7.10 .align 16,0x90 # LOE # mark_end; .type _Z1fv,@function .size _Z1fv,.-_Z1fv .data # -- End _Z1fv .data .section .note.GNU-stack, "" # End </code></pre> <p>As you can see at ..B1.1, Intel compiles "return shift(42,0)" to "return 42."</p> <p>Intel 11 also culls the shift for these two variations:</p> <pre><code>int g() { int a = 5; int b = 5; return shift(42,a-b); } int h(int k) { return shift(42,k*0); } </code></pre> <p>For the case when the shift value is unknowable at compile time ...</p> <pre><code>int egad(int m, int n) { return shift(42,m-n); } </code></pre> <p>... the shift cannot be avoided ...</p> <pre><code># -- Begin _Z4egadii # mark_begin; .align 16,0x90 .globl _Z4egadii _Z4egadii: # parameter 1: 4 + %esp # parameter 2: 8 + %esp ..B1.1: # Preds ..B1.0 movl 4(%esp), %ecx #20.5 subl 8(%esp), %ecx #21.21 movl $42, %eax #21.10 shrl %cl, %eax #21.10 ret #21.10 .align 16,0x90 # LOE # mark_end; </code></pre> <p>... but at least it's inlined so there's no call overhead.</p> <p>Bonus assembly: volatile is expensive. The source ...</p> <pre><code>int g() { int a = 5; volatile int b = 5; return shift(42,a-b); } </code></pre> <p>... instead of a no-op, compiles to ...</p> <pre><code>..B3.1: # Preds ..B3.0 pushl %esi #10.9 movl $5, (%esp) #12.18 movl (%esp), %ecx #13.21 negl %ecx #13.21 addl $5, %ecx #13.21 movl $42, %eax #13.10 shrl %cl, %eax #13.10 popl %ecx #13.10 ret #13.10 .align 16,0x90 # LOE # mark_end; </code></pre> <p>... so if you're working on a machine where values you push on the stack might not be the same when you pop them, well, this missed optimization is likely the least of your troubles.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload