<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Thanks John.<div><br><div><div>On Oct 22, 2010, at 4:17 PM, John McCall wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 22, 2010, at 3:49 PM, Ted Kremenek wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 22, 2010, at 10:59 AM, Marcin Świderski wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">W dniu 22 października 2010 11:22 użytkownik Zhongxing Xu<span class="Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:xuzhongxing@gmail.com">xuzhongxing@gmail.com</a>></span><span class="Apple-converted-space"> </span>napisał:<br><blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">When the binary operator is logical operator, why we need to replicate the control flow when adding the dtors in LHS and RHS? Could we just add the dtor right after where the LHS and RHS are evaluated?<br><br>That is, for code<br><br>A && B<br><br>we generate CFG like this:<br><br>A && B<br>~A()<br>|      \<br>|       B<br>|       ~B()<br>|        |<br>A && B<br><br>Since in logical binary operator, we only need the boolean value. The temporary object can be destroyed right after it is evaluated.<br><br></blockquote><div>This depends on how much we want to simulate real control flow of expression. C++ standard states that destructors of temporaries should be called at the end of full expression and in reverse order of their construction. Your example does not satisfy this. It only guaranties that destructor for temporary will be called.</div></span></blockquote></div><div><br></div><div>I think Zhongxing is right.  Here is what the compiler does:</div></div></blockquote><div><br></div>Marcin is right;  the temporary is destroyed conditionally at the end of the full expression.  It just happens to be the case that that immediately follows the call to 'B::operator bool()' in your example.  You can see that easily in the following modification to your example:</div><div><br></div><div>void baz(bool);</div><div>int test() {</div><div>  foo(foo() || bar());</div><div>}</div><div><br></div><div><div>test():                              ## @_Z4testv</div><div>Leh_func_begin0:</div><div>## BB#0:                                ## %entry</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>pushq<span class="Apple-tab-span" style="white-space:pre">       </span>%rbp</div><div>Ltmp0:</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rsp, %rbp</div><div>Ltmp1:</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>pushq<span class="Apple-tab-span" style="white-space:pre">       </span>%r14</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>pushq<span class="Apple-tab-span" style="white-space:pre">       </span>%rbx</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>subq<span class="Apple-tab-span" style="white-space:pre">        </span>$16, %rsp</div><div>Ltmp2:</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>leaq<span class="Apple-tab-span" style="white-space:pre">        </span>-24(%rbp), %rbx</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbx, %rdi</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>foo()</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbx, %rdi</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>A::operator bool()</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>cmpb<span class="Apple-tab-span" style="white-space:pre">        </span>$1, %al</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>jne<span class="Apple-tab-span" style="white-space:pre"> </span>LBB0_2</div><div>## BB#1:                                ## %lor.end.thread7</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>movl<span class="Apple-tab-span" style="white-space:pre">        </span>$1, %edi</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>baz(bool)</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>jmp<span class="Apple-tab-span" style="white-space:pre"> </span>LBB0_3</div><div>LBB0_2:                                 ## %temp.cond-dtor.call</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>leaq<span class="Apple-tab-span" style="white-space:pre">        </span>-32(%rbp), %rbx</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbx, %rdi</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>bar()</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbx, %rdi</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>B::operator bool()</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>movzbl<span class="Apple-tab-span" style="white-space:pre">      </span>%al, %edi</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>baz(bool)</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>movl<span class="Apple-tab-span" style="white-space:pre">        </span>%eax, %r14d</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbx, %rdi</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>B::~B()</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>movl<span class="Apple-tab-span" style="white-space:pre">        </span>%r14d, %eax</div><div>LBB0_3:                                 ## %temp.cond-dtor.cont</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>movl<span class="Apple-tab-span" style="white-space:pre">        </span>%eax, %ebx</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>leaq<span class="Apple-tab-span" style="white-space:pre">        </span>-24(%rbp), %rdi</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>callq<span class="Apple-tab-span" style="white-space:pre">       </span>A::~A()</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>movl<span class="Apple-tab-span" style="white-space:pre">        </span>%ebx, %eax</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>addq<span class="Apple-tab-span" style="white-space:pre">        </span>$16, %rsp</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>popq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbx</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>popq<span class="Apple-tab-span" style="white-space:pre">        </span>%r14</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>popq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbp</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>ret</div><div><br></div><div>Er, actually, the optimizer has helpfully cloned the call to 'baz' so as to obscure my point, but I think you get it.</div><div><br></div><div>John.</div></div></div></blockquote></div><br></div></body></html>