A common, but ugly, pattern in Gecko's C++ code is:
#ifdef DEBUG bool ok = #endif FunctionWithReturnValueThatShouldAlwaysBeTrue(); ASSERT(ok);
Why do this? Assertions are (usually) only checked in
DEBUG builds. In release builds, there's no point in declaring the
ok variable, because it's not going to be used. Worse, declaring a variable but not using it generates a compiler warning, and unused variables can additionally incur a small cost from being allocated a stack slot and/or register (depending on how the compiler optimizes the code). So, we write these ugly little warts to avoid compiler warnings and small runtime overhead from unused variables.
DebugOnly<T> helper provides a cleaner way to avoid these compiler warnings and the runtime overhead mentioned above. With
DebugOnly, the example above could be rewritten as:
DebugOnly<bool> ok = FunctionWithReturnValueThatShouldAlwaysBeTrue(); ASSERT(ok);
DEBUG builds, the
ok variable behaves as if it had been declared
bool ok, so it can be used in assertions etc. as in the example above. And in release builds, the
ok variable doesn't occupy storage space or incur a runtime overhead. In fact, any attempt to use the value of
ok in a release build generates a compiler error.
DebugOnly<T>is a "stack class", variables of which are only intended to be declared on the stack. If you declare one as a member variable of a class, for example, it will behave differently than described above. Don't do that!