Add Macro to detect whether jasserts (and DBG) are on or not

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