title: Why does using the ternary operator to return a string generate considerably different code from returning in an equivalent if/else block?
body: <p>I was playing with the Compiler Explorer and I stumbled upon an interesting behavior with the ternary operator when using something like this:</p>
  <pre><code>std::string get_string(bool b)
  {
      return b ? &quot;Hello&quot; : &quot;Stack-overflow&quot;;
  }
  </code></pre>
  <p>The compiler generated code for this (clang trunk, with -O3) is this:</p>
  <pre><code>get_string[abi:cxx11](bool):                 # @get_string[abi:cxx11](bool)
          push    r15
          push    r14
          push    rbx
          mov     rbx, rdi
          mov     ecx, offset .L.str
          mov     eax, offset .L.str.1
          test    esi, esi
          cmovne  rax, rcx
          add     rdi, 16 #&lt; Why is the compiler storing the length of the string
          mov     qword ptr [rbx], rdi
          xor     sil, 1
          movzx   ecx, sil
          lea     r15, [rcx + 8*rcx]
          lea     r14, [rcx + 8*rcx]
          add     r14, 5 #&lt; I also think this is the length of &quot;Hello&quot; (but not sure)
          mov     rsi, rax
          mov     rdx, r14
          call    memcpy #&lt; Why is there a call to memcpy
          mov     qword ptr [rbx + 8], r14
          mov     byte ptr [rbx + r15 + 21], 0
          mov     rax, rbx
          pop     rbx
          pop     r14
          pop     r15
          ret
  .L.str:
          .asciz  &quot;Hello&quot;
  
  .L.str.1:
          .asciz  &quot;Stack-Overflow&quot;
  </code></pre>
  <p>However, the compiler generated code for the following snippet is considerably smaller and with no calls to <code>memcpy</code>, and does not care about knowing the length of both strings at the same time. There are 2 different labels that it jumps to</p>
  <pre><code>std::string better_string(bool b)
  {
      if (b)
      {
          return &quot;Hello&quot;;
      }
      else
      {
          return &quot;Stack-Overflow&quot;;
      }
  }
  </code></pre>
  <p>The compiler generated code for the above snippet (clang trunk with -O3) is this:</p>
  <pre><code>better_string[abi:cxx11](bool):              # @better_string[abi:cxx11](bool)
          mov     rax, rdi
          lea     rcx, [rdi + 16]
          mov     qword ptr [rdi], rcx
          test    sil, sil
          je      .LBB0_2
          mov     dword ptr [rcx], 1819043144
          mov     word ptr [rcx + 4], 111
          mov     ecx, 5
          mov     qword ptr [rax + 8], rcx
          ret
  .LBB0_2:
          movabs  rdx, 8606216600190023247
          mov     qword ptr [rcx + 6], rdx
          movabs  rdx, 8525082558887720019
          mov     qword ptr [rcx], rdx
          mov     byte ptr [rax + 30], 0
          mov     ecx, 14
          mov     qword ptr [rax + 8], rcx
          ret
  </code></pre>
  <p>The same result is when I use the ternary operator with:</p>
  <pre><code>std::string get_string(bool b)
  {
      return b ? std::string(&quot;Hello&quot;) : std::string(&quot;Stack-Overflow&quot;);
  }
  </code></pre>
  <p>I would like to know why the ternary operator in the first example generates that compiler code. I believe that the culprit lies within the <code>const char[]</code>.</p>
  <p>P.S: GCC does calls to <code>strlen</code> in the first example but Clang doesn't.</p>
  <p>Link to the Compiler Explorer example: <a href="https://godbolt.org/z/Exqs6G" rel="noreferrer">https://godbolt.org/z/Exqs6G</a></p>
  <p>Thank you for your time!</p>
  <p><em>sorry for the wall of code</em></p>