Lately I've been finding Rust's dbg!() macro[1] useful for quick debugging.  
Its main usefulness is in avoiding the need to extract out an expression into a 
separate variable just so that you can print out its value and then use the 
value in its original context.

I wanted something similar for C++, so in bug 1538081, which just landed on 
autoland, I've added the MOZ_DBG macro.

MOZ_DBG can be added around almost any kind of expression[2], as long as there 
is an operator<<(ostream&, ...) defined for its type.  I added operator<< 
definitions for nsAString, nsACString, mozilla::Span, nsTArray, mozilla::Array, 
and T[N], since they seemed useful.  And as a special case, if you wrap MOZ_DBG 
around a pointer value, then it will use the operator<< of the dereferenced 
object (if the operator<< exists, and the pointer is non-null), and otherwise 
just prints out the pointer value.  The output goes to stderr.

The macro is defined in mfbt/DbgMacro.h, but I've included it into nsDebug.h, 
so that it should be available in most files without needing to explicitly 
#include <mozilla/DbgMacro.h>.  It's available in non-DEBUG builds, but not in 
MOZILLA_OFFICIAL builds.

Example:

  nsTArray<int> numbers;
  MOZ_DBG(numbers = { MOZ_DBG(123 * 1), MOZ_DBG(123 * 2) });
  MOZ_DBG(numbers[MOZ_DBG(numbers.Length() - 1)]);
  MOZ_DBG(numbers) = { 789 };
  MOZ_DBG(numbers);

Output:

  [/path/to/file.cpp:319] 123 * 1 = 123
  [/path/to/file.cpp:319] 123 * 2 = 246
  [/path/to/file.cpp:319] numbers = { MOZ_DBG(123 * 1), MOZ_DBG(123 * 2) } = 
[123, 246]
  [/path/to/file.cpp:320] numbers.Length() - 1 = 1
  [/path/to/file.cpp:320] numbers[MOZ_DBG(numbers.Length() - 1)] = 246
  [/path/to/file.cpp:321] numbers = [123, 246]
  [/path/to/file.cpp:322] numbers = [789]

There is also a macro MOZ_DEFINE_DBG, which can be used to define an operator<< 
for a class.  It's like a poor imitation of #[derive(Debug)].

Example:

  struct Point {
    int x;
    int y;

    MOZ_DEFINE_DBG(Point, x, y)
  };

  Point p{10, 20};
  MOZ_DBG(p);

Output:

  [/path/to/file.cpp:100] p = Point { x = 10, y = 20 }


[1] https://doc.rust-lang.org/stable/std/macro.dbg.html
[2] One specific case where it won't work is if you are wrapping it around a 
prvalue being used to initialize an object, and the type of that value is 
something that doesn't have a copy or move constructor available.  Such types 
should be rare, though, and you'll get a compiler error if you try.
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to