<div dir="ltr"><div>On Tue, Oct 11, 2016 at 9:22 PM, Zachary Turner via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">A while back llvm::format() was introduced that made it possible to combine printf-style formatting with llvm streams.  However, this still comes with all the risks and pitfalls of printf.  Everyone is no-doubt familiar with these problems, but here are just a few anyway:<div><br></div><div>1. <b>Not type-safe.</b>  Not all compilers warn when you mess up the format specifier.  And when you're writing your own Printf-like functions, you need to tag them with __attribute__(format, printf) which again not all compilers have.  If you change a const char * to a StringRef, it can silently succeed while passing your StringRef object to printf.  It should fail to compile!</div><div><br></div><div>2. <b>Not security safe.  </b>Functions like sprintf() will happily smash your stack for you if you're not careful.  </div><div><br></div><div>3. <b>Not portable (well kinda).  </b>Quick, how do you print a size_t?  You probably said %z.  Well MSVC didn't even support %z until 2015, which we aren't even officially requiring yet.  So you've gotta write (uint64_t)x and then use PRIx64.  Ugh.</div><div><br></div><div>4. <b>Redundant.</b>  If you're giving it an integer, why do you need to specify %d?  It's an integer!  We should be able to use the type system to our advantage.</div><div><br></div><div>5. <b>Not flexible.</b>  How do you print a std::chrono::time_point with llvm::format()?  You can't.  You have to resort to providing an overloaded streaming operator or formatting it some other way.</div><div><br></div><div>So I've been working on a library that will solve all of these problems and more.</div></div></blockquote><div><br></div><div><br></div><div>I wonder what use cases you envision for this? Why does LLVM need a super extensible flexible formatting library? I mean -- if you were developing this as a standalone project, that seems like maybe a nice feature. But I see no rationale as to why LLVM should include it.</div><div><br></div><div>That is to say: wouldn't a much-simpler printf replacement, implemented with variadic templates instead of C varargs (and which therefore doesn't require size/signedness prefixes on %d) be sufficient for LLVM?</div><div><br></div><div>You can do that as a drop-in improvement for llvm::format, replacing the call to snprintf inside the implementation with a new implementation that actually uses the type information.<br></div></div></div></div>