<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 19, 2015, at 7:40 AM, Yaron Keren <<a href="mailto:yaron.keren@gmail.com" class="">yaron.keren@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="rtl" class=""><div dir="ltr" class="">A very common code pattern in LLVM is</div><div dir="ltr" class=""><br class=""></div><div dir="ltr" class=""><font face="monospace, monospace" class=""> SmallString<128> S;</font></div><div dir="ltr" class=""><font face="monospace, monospace" class=""> raw_svector_ostream OS(S);<br class=""></font></div><div dir="ltr" class=""><font face="monospace, monospace" class=""> OS<< ...</font></div><div dir="ltr" class=""><font face="monospace, monospace" class=""> Use OS.str()</font></div><div dir="ltr" class=""><br class=""></div><div dir="ltr" class="">While raw_svector_ostream is smart to share the text buffer itself, it's inefficient keeping two sets of pointers to the same buffer:</div><div dir="ltr" class=""><br class=""></div><div dir="ltr" class=""> In SmallString: void *BeginX, *EndX, *CapacityX<br class=""></div><div dir="ltr" class=""> In raw_ostream: char *OutBufStart, *OutBufEnd, *OutBufCur<br class=""></div><div dir="ltr" class=""><br class=""></div><div dir="ltr" class="">Moreover, at runtime the two sets of pointers need to be coordinated between the SmallString and raw_svector_ostream using raw_svector_ostream::init, raw_svector_ostream::pwrite, raw_svector_ostream::resync and raw_svector_ostream::write_impl.</div><div dir="ltr" class="">All these functions have non-inlined implementations in raw_ostream.cpp. </div><div dir="ltr" class=""><br class=""></div><div dir="ltr" class="">Finally, this may cause subtle bugs if S is modified without calling OS::resync(). This is too easy to do by mistake.</div></div></div></blockquote><div><br class=""></div><div>FWIW I’ve been bitten exactly by this last week while updating an out-of-tree compiler to adapt API changes around streams (raw_pwrite_stream). On the positive aspect, I had to learn about the internal of the various streams ;)</div><div><br class=""></div><div>The API for raw_svector_ostream is not nice on this aspect, but what is really missing is that there is no assertion to catch it.</div><div>I feel it is a bit off from the principle “easy to use, hard to misuse”.</div><div><br class=""></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="rtl" class=""><div dir="ltr" class="">In this frequent case usage the client does not really care about S being a SmallString with its many useful string helper function. It's just boilerplate code for raw_svector_ostream. But it does cost three extra pointers, some runtime performance and possible bugs.</div><div dir="ltr" class=""><br class=""></div><div dir="ltr" class="">To solve all three issues, would it make sense to have raw_ostream-derived container with a its own SmallString like templated-size built-in buffer?</div></div></div></blockquote><div><br class=""></div><div>Not sure about the exact solution, but “something” could certainly be done to be more “user-friendly”. </div><div><br class=""></div><div>— </div><div>Mehdi</div><div><br class=""></div></div></body></html>