zturner added a comment.
In https://reviews.llvm.org/D27459#614670, @clayborg wrote:
> Part of the reason I like the current "if (log) log->Printf()" is that it
> doesn't cost you much if logging isn't enabled. So if you have a log line
> like:
>
> if (log)
> log->Printf("%s %s %s", myStringRef1.str().c_str(),
> myStringRef2.str().c_str(), myStringRef3.str().c_str());
>
>
> And switch over to using:
>
> LLDB_LOG() << myStringRef1 << " " << myStringRef2 << " " << myStringRef2;
>
>
> You end up doing some work with all of the types regardless of wether the
> logging is enabled. We tend to do pretty heavy logging in places and I really
> don't want performance impacted (the expression parser emits a full novel
> worth of information when logging is enabled), nor would I want people to log
> less because they are worried about affecting performance.
>
> So any solution should have very minimal cost if logging isn't enabled. We
> also do log channels, so any design will need to include the ability to log
> to a channel, any channel, or only if all channels are enabled.
>
> The other thing I don't like about streams is they are harder to read over a
> printf style log string. I wrote all of dwarfdump and used the full power off
> C++ streams and I regret doing this as all of the code is really hard to
> read. I also didn't like the fact that streams maintain state and can affect
> things down the line. If we adopt LLVM style streams I believe they don't
> suffer from the C++ streams having state issue. But with C++ you can do this:
Take a look at `llvm::formatv`. I wrote this in LLVM specifically to be the
best of both worlds. You get all the flexibility and conciseness of printf
with all the type safety of streams. Example:
// Printf style
log->Printf("%d %s %z", 12, "test", (size_t)7);
// Stream style
*log << 12 << "test" << (size_t)7;
// formatv style
*log << llvm::formatv("{0} {1} {2}", 12, "test", (size_t)7);
// alternative formatv sytle
log->Formatv("{0} {1} {2}", 12, "test", (size_t)7);
As you can see, you don't have to specify the type. All the ugliness about
`PRIx64`, compiler inconsistencies, platform-dependent sizes, etc all disappear
because it deduces the type. And it's even better than this, because you can
write custom formatters for your own types. For examples, LLDB has a class
called `AddressRange`. With printf you would have to write this
`log->Printf("%llu - %llu", range.first(), range.second())', but with `formatv`
you can write this: `log->Formatv("{0}", range);` as long as it can find a
formatter somewhere. And formatters can define arbitrary style options too, so
you could write something like `log->Formatv("{0:abc}", range);` and this
string "abc" would get passed to the formatter's format function. This is
useful when a type is often formatted different ways (precision, optional
fields, etc).
I strongly recommend moving to this for all printf style formatting moving
forward.
https://reviews.llvm.org/D27459
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits