This seems very much inspired by the `dbg` macro recently introduced in Rust. [1]<p>Which in turn was inspired by Haskell s `Debug.Trace` functions [2].<p>It's definitely a convenient tool if you can't use a debugger or want to follow more complex interactions.<p>[1]<a href="https://doc.rust-lang.org/std/macro.dbg.html" rel="nofollow">https://doc.rust-lang.org/std/macro.dbg.html</a><p>[2] <a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Debug-Trace.html" rel="nofollow">https://hackage.haskell.org/package/base-4.12.0.0/docs/Debug...</a>
Would be nice to offer runtime enable/disable. Out of curiosity, I wrote a little benchmark and submitted as a PR: <a href="https://github.com/sharkdp/dbg-macro/pull/57" rel="nofollow">https://github.com/sharkdp/dbg-macro/pull/57</a><p>The key idea is that modern CPUs dynamically branch-predict-away if-statements that are rarely/never invoked, such as a dynamically disabled dbg() call.<p>With the performance difference magnified 10x by loop unrolling, this is what I'm seeing on my Mac laptop:<p>830000000 iterations in 3 secs = 2.76667e+08 iters/sec (compiled-out).
840000000 iterations in 3 secs = 2.8e+08 iters/sec (dynamically disabled).<p>And this is the worst case, where the whole program does nothing but call dbg() - real world programs contain lots of other real work, drowning the minute difference in performance, i.e. in a real program I doubt you'd see even 0.1% total performance difference, littering it with dynamic dbg() statements.<p>p.s. my C/C++ is pretty rusty - feedback welcome, but pls be kind.
I wrote and use regularly similar macros in C++ context.<p>They are less advanced on some areas, but more advanced on some.<p>Particularly nice features:<p>* a structured log indented by stack trace depth (fully portable, put a simple macro at function start, will log start and any exit)<p>* log any expression: `somemacro(foo.bar())` will log `foo.bar() = 42`<p>* log scopes like functions<p>* with possibility to jump to source code line on one click or keypress<p>* browse the log with structured jumps (like step into function vs advance one line, back and forth)<p>...just by generating a text format that is parsed by common pre-existing tools (namely emacs compilation-mode and a few other short settings).<p>I've been planning to share that for a moment. It will eventually appear on <a href="https://github.com/fidergo-stephane-gourichon?tab=repositories" rel="nofollow">https://github.com/fidergo-stephane-gourichon?tab=repositori...</a><p>I wrote a similar set of macros for C, see my comment <a href="https://news.ycombinator.com/item?id=21071497" rel="nofollow">https://news.ycombinator.com/item?id=21071497</a> on eerimoq's "Show HN" <a href="https://news.ycombinator.com/item?id=21040649" rel="nofollow">https://news.ycombinator.com/item?id=21040649</a>
Mozilla has something similar in Gecko's codebase, inspired by the Rust macro: <a href="https://searchfox.org/mozilla-central/source/mfbt/DbgMacro.h" rel="nofollow">https://searchfox.org/mozilla-central/source/mfbt/DbgMacro.h</a>
I wrote something similar a couple years ago, except my macro automatically compiled to a no op if compiled in release mode, which is very convenient for switching back-and-forth to the testing.
Oh ... this is really neat. I like how you can wrap an subexpression or prettyprint vectors.<p>When the debugger is too cumbersome to use good old prints is always a nice fallback.
The name reminds me of <a href="https://metacpan.org/pod/DBG" rel="nofollow">https://metacpan.org/pod/DBG</a>, which, full disclosure, I wrote. Not that it's nearly as cool or likely to be used by anyone, but ... it has a superficial resemblance.
I did one of these for C(or at least gcc/llvm c) but it's a lot harder to abstract over types in c so it's a bit more limited<p><a href="https://github.com/rtaycher/debug_print" rel="nofollow">https://github.com/rtaycher/debug_print</a>
Nice idea! I would appreciate a warning from the author specifying whether dbg evaluates its argument twice, as if so one must be careful with side effects when using it.
This feels like too much of a "ricer" feature, at least the way it's implemented.<p>Instead, you want:<p>* A pretty-printer library (possibly single-header)
* A function for obtaining the typename; see:<p><pre><code> https://stackoverflow.com/q/35941045/1593077
https://stackoverflow.com/a/56766138/1593077
for a constexpr approach.
</code></pre>
and it won't hurt to have:<p>* A logging library with log levels (so that you don't necessarily need to recompile to enable these outputs)
* A stack trace printing library<p>When you have that, such a macro becomes nearly trivial. Oh, yeah, and - drop the silly ANSI coloring.