jassert
and DBG
only do something in case
(JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS) || DOXYGEN
is true.
This means that code like this:
void f (std::vector<int> v)
{
for (int x : v)
jassert (x > 0);
...
}
will trigger a warning in release builds about x
being unused, unless the loop is wrapped with an #if
on the same macro condition:
void f (std::vector<int> v)
{
#if (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS) || DOXYGEN
for (int x : v)
jassert (x > 0);
#endif
...
}
This is both non-DRY (maybe the macro will change in the future) and cumbersome. It would be nice if there were a macro (e.g. JUCE_ASSERTIONS_ENABLED
) which would be defined, or not, according to the more complex macro condition, and could then be used in user code.
Aside: Does it make sense that DBG
is currently enabled/disabled according to the above macro condition? If I use JUCE_DISABLE_ASSERTIONS
, I might still want to see debug prints.
Thanks,
Dan
Hmm, (and maybe this wouldn’t help you anyway if you’re not on C++17) – can you use attributes on a declaration inside a range for()
like that? Something like:
for ([[maybe_unused]] int x: v)
jassert(x > 0);
?
1 Like
That would work, but I think the macro-based is less bug-prone.
Think a case where some real logic code regarding x
is added to the loop body, then later erroneously removed, leaving x
unused again (in release builds, at least). With the attribute, there’s a good chance the attribute wouldn’t be deleted when the real logic is added, so when it is erroneously removed there would be no warning.
In contrast, the macro would probably be removed at the time the real logic is added. So when it is removed, you get the warning again and decide what to do about it (fix a bug, re-suppress the warning, remove the loop entirely).
You could also do…
void f (std::vector<int> v)
{
for (int x : v)
{
ignoreUnused (x);
jassert (x > 0);
}
}
1 Like
Stumbled upon this old post: Note this case is now resolved by using jassertquiet
, see Make jassert use ignoreUnused internally - #20 by reuk
1 Like