<div dir="ltr">That's less efficient, more verbose, involves extra copies, and doesn't allow you to take full advantage of the library's mechanism for formatting user-defined types using different presentation styles.  <div><br></div><div>Just to be clear, no other format libraries that exist today mandate string literal format strings.  And it would be an understatement to say that I would be strongly opposed to such a requirement.</div><div><br></div><div>I would be fine providing UDLs for the case where you have a string literal format string and encouraging people to use it wherever possible, but I don't consider providing *only* UDL-based formatting (or any mechanism that mandates string literals) a viable option.</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 12, 2016 at 12:40 PM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com">mehdi.amini@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Oct 12, 2016, at 12:35 PM, Zachary Turner <<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>> wrote:</div><br class="m_2199539448367041103Apple-interchange-newline gmail_msg"><div class="gmail_msg">You get compile time checking automatically when we can use c++14 though.  If you use it with a string literal, you'll get compile time checking, otherwise you won’t.<br class="gmail_msg"></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I understand that, but that doesn’t really address my concerns.</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg">Here's a different example though.  Suppose you're writing a tool which prints formatted output, and the field width is specified by the user.  </div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">Now you NEED to build the format string at runtime, there's no other way</div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">Maybe the problem is using a string to format this in the first place.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">For example, you could wrap the object you want to print with an adaptor in charge of padding to the right till you reach the column width.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">format(“{0}”, rPad(col_width, my_object));</div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">.  Off the top of my head, lldb does this already when printing disassembly and stack frames.  The column widths are user settings <br class="gmail_msg"></div></blockquote><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Wed, Oct 12, 2016 at 12:23 PM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="gmail_msg" target="_blank">mehdi.amini@apple.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Oct 12, 2016, at 12:08 PM, Zachary Turner <<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>> wrote:</div><br class="gmail_msg m_2199539448367041103m_-217664310620620434Apple-interchange-newline"><div class="gmail_msg"><div dir="ltr" class="gmail_msg">I thought I did.  :)  Passing format strings between functions is very useful.  For example, imagine wanting to write a function like printRange(const char *Fmt, std::vector<int> Items);</div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I’m not sure I understand your example? </div><div class="gmail_msg">Do you mean you want the range to be in the format? If so Why? I would rather write something like:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">printRange(“{per_elts_fmt}”, /* separator */ “, ", begin, end);</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="gmail_msg">This isn't possible if your format string MUST be a string literal</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I haven’t seen a convincing example yet to support this. I may miss the obvious, but you haven’t shown it either.</div><div class="gmail_msg">One could find a way to *compose* format in a compile-time-safe more efficiently.</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="gmail_msg">Equally importantly, I don't see a good reason to disallow runtime format strings.</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">No compile time checking, bug hiding, not robust.</div><div class="gmail_msg">(i.e. you may not “crash”, but you may still don’t print what you want / expect in every case).</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">— </div><div class="gmail_msg">Mehdi</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Wed, Oct 12, 2016 at 11:59 AM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="gmail_msg" target="_blank">mehdi.amini@apple.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Oct 12, 2016, at 11:38 AM, Zachary Turner <<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>> wrote:</div><br class="gmail_msg m_2199539448367041103m_-217664310620620434m_-2338646459629889805Apple-interchange-newline"><div class="gmail_msg"><div dir="ltr" class="gmail_msg">I don't object to compile time checking *as long as it doesn't severely detract from brevity*.  </div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg">At the same time, I do object to *preventing* runtime format strings.</div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">You haven’t answered: why?</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">— </div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">Mehdi</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">When we have C++14, we can make every member of StringRef constexpr, and at that point we will get compile time checking mostly "for free" without preventing runtime format strings.  For example, given a constexpr-aware implementation of StringRef, if you were to write: os.format("literal format", a, b, c) you would get all the compile time checking, such as ensuring that the number of arguments matches the highest index in the format string, and ensuring there are enough arguments for every placeholder.  But if you wrote os.format(s, a, b, c) you would still get runtime checking of the format strings.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">As long as the runtime implementation doesn't exhibit UB when things don't match up, and it kindly asserts to warn you of the problem in the test suite, support runtime format strings can be very helpful.  For example, it could allow you to wrap a call to format in some other function, like:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">template<typename... Ts></div><div class="gmail_msg">void wrap_format(const char *Format, Ts &&... Args) {</div><div class="gmail_msg">   dbgs().format(Format, ConvertArg(Args)...);</div><div class="gmail_msg">}</div></div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Wed, Oct 12, 2016 at 11:24 AM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="gmail_msg" target="_blank">mehdi.amini@apple.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Oct 12, 2016, at 7:12 AM, Zachary Turner via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="gmail_msg m_2199539448367041103m_-217664310620620434m_-2338646459629889805m_931657296345544509Apple-interchange-newline"><div class="gmail_msg">Ahh, UDLs also wouldn't permit non literal format strings, which is a deal breaker imo<br class="gmail_msg"></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">Why?</div><div class="gmail_msg">Somehow the goal pursued by Pavel (which you didn’t object per-se) is to provide *compile* time checking.</div><div class="gmail_msg">This imply that you cannot decouple the construction of the format and the argument list.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">— </div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">Mehdi</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Wed, Oct 12, 2016 at 7:03 AM Zachary Turner <<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I'm not sure that would work well.  The implementation relies on being able to index into the parameter pack.  How would you do that if each parameter is streamed in?<br class="gmail_msg"><br class="gmail_msg">"{0} {1}"_fs(1, 2)<br class="gmail_msg"><br class="gmail_msg">Could perhaps work, but it looks a little strange to me.<br class="gmail_msg"><br class="gmail_msg">Fwiw i agree format_string is long.  Ideally it would be called format, but that's taken.<br class="gmail_msg"><br class="gmail_msg">Another option is os.format("{0}", 7), and have format_string("{0}", 7) return a std::string.<br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Wed, Oct 12, 2016 at 6:43 AM Aaron Ballman <<a href="mailto:aaron@aaronballman.com" class="gmail_msg" target="_blank">aaron@aaronballman.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">>> 1. os << format_string("Test");   // writes "test"<br class="gmail_msg">
>> 2. os << format_string("{0}", 7);  // writes "7"<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> The "<< format_string(..." is ... really verbose for me. It also makes me<br class="gmail_msg">
> strongly feel like this produces a string rather than a streamable entity.<br class="gmail_msg">
<br class="gmail_msg">
I wonder if we could use UDLs instead?<br class="gmail_msg">
<br class="gmail_msg">
os << "Test" << "{0}"_fs << 7;<br class="gmail_msg">
<br class="gmail_msg">
~Aaron<br class="gmail_msg">
<br class="gmail_msg">
><br class="gmail_msg">
> I'm not a huge fan of streaming, but if we want to go this route, I'd very<br class="gmail_msg">
> much like to keep the syntax short and sweet. "format" is pretty great for<br class="gmail_msg">
> that. If this is going to fully subsume its use cases, can we eventually get<br class="gmail_msg">
> that to be the name?<br class="gmail_msg">
><br class="gmail_msg">
> (While I don't like streaming, I'm not trying to fight that battle here...)<br class="gmail_msg">
><br class="gmail_msg">
> Also, you should probably look at what is quickly becoming a popular C++<br class="gmail_msg">
> library in this space: <a href="https://github.com/fmtlib/fmt" rel="noreferrer" class="gmail_msg" target="_blank">https://github.com/fmtlib/fmt</a><br class="gmail_msg">
><br class="gmail_msg">
> _______________________________________________<br class="gmail_msg">
> LLVM Developers mailing list<br class="gmail_msg">
> <a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg">
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="gmail_msg">
><br class="gmail_msg">
</blockquote></div></blockquote></div>
_______________________________________________<br class="gmail_msg">LLVM Developers mailing list<br class="gmail_msg"><a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg"><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="gmail_msg"></div></blockquote></div></div></blockquote></div>
</div></blockquote></div></div></blockquote></div>
</div></blockquote></div></div></blockquote></div>
</div></blockquote></div><br class="gmail_msg"></div></blockquote></div>