I should probably add to the Cons that it requires a global variable which is normally considered bad practice.
The more I look at this the more I think that the safest way to achieve a generic solution without asking everyone else using JUCE to take on unnecessary changes is to read the logger as I have done in my current implementation. Without changes to JUCE all cases will require JUCE_LOG_ASSERTIONS to be defined or the jassert macro will just be defined as empty.
A question for @jules however, is this really needed in juce_PlatformDefs.h
#if JUCE_LOG_ASSERTIONS
#define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;)
#else
#define jassert(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON ( ; )
#endif
When you already have this earlier on in the file?
#if JUCE_LOG_ASSERTIONS || JUCE_DEBUG
#define JUCE_LOG_CURRENT_ASSERTION juce::logAssertion (__FILE__, __LINE__);
#else
#define JUCE_LOG_CURRENT_ASSERTION
#endif
Can we not rely on the compiler to optimise away the code for us as you have with jassertfalse
?
If we can rely on the compiler to optimise away the code then wrapping the definition of JUCE_LOG_CURRENT_ASSERTION
with an #ifndef JUCE_LOG_CURRENT_ASSERTION
would mean that projects can easily redefine what happens in the case of an assertion which would be useful in this scenario and keeps the changes to JUCE to a minimum.
Also I think I may have discovered some slightly odd behaviour, if JUCE_DEBUG
and JUCE_DISABLE_ASSERTIONS
are both defined as 1
then DBG() will no longer print which I think is unexpected, however if DBG() is simply redefined jassertfalse will print an assertion because it currently calls logAsserton() in this scenario (it just doesn’t do anything except create a string) while jassert will continue to not print assertions. I suspect few people if any are actually using JUCE_DISABLE_ASSERTIONS
.
UPDATE:
I’ve just realised that if jassert is changed as I have suggested above then expressions which change state will stop it from being optimised away, and potentially will change behaviour of existing code (I could see how this could be considered both a good and a bad thing, but ultimately it’s a change in behaviour which on balance is probably negative), I guess there are other expressions that may prevent the optimisation too.
So I think I would stick with my original suggestion of reading the log and static_asserts if any of the expectJassert… macros are used when JUCE_LOG_ASSERTIONS
or JUCE_DEBUG
is not 1
or JUCE_DISABLE_ASSERTIONS
is 1