electro-smith / DaisySP

A Powerful DSP Library in C++
https://www.electro-smith.com/daisy
Other
836 stars 131 forks source link

Add platform dependent assert macro #158

Open TheSlowGrowth opened 3 years ago

TheSlowGrowth commented 3 years ago

It would be great to have a platform-independent way for assertions (e.g. bkpt 255 on ARM, assert(), etc.).

  1. Create Source/platform.h
  2. Add macro D_SP_ASSERTFALSE that triggers an assertion. The JUCE macro jassertfalse could serve as a template and could be extended for bkpt 255 when compiling for embedded targets.
  3. Add macro D_SP_ASSERT(bool condition) that triggers D_SP_ASSERTFALSE if !condition
  4. Replace all existing assertions with these macros

The same file could also be very useful in libDaisy.

polyclash commented 3 years ago

JUCE dependancy need to be optional, not an default bet.

TheSlowGrowth commented 3 years ago

Im not suggesting to add a dependency on JUCE. Rather I'd use the jassert macro from JUCE as an inspiration for our own implementation. JUCE has a lot of the platforms and compilers covered so it would help to look at their implementation.

dylan-robins commented 3 years ago

Another possibility may be to define the behaviour we want on embedded platforms, and in the case that DaisySP is being used in the context of a JUCE project we can fall back on their implementations. So something like :

// Define macro D_SP_ASSERTFALSE which triggers an assertion failure using the
// appropriate method for the current platform
#if defined(__arm__)
// On embedded platforms use the bkpt opcode
#define D_SP_ASSERTFALSE(expr) asm("bkpt 255")
#elif defined(JUCE_VERSION)
// In a JUCE project use the JUCE macros
#define D_SP_ASSERTFALSE(expr) jassertfalse
#else
// Otherwise, raise a default assertion failure
#include <assert.h>
#define D_SP_ASSERTFALSE(expr) assert(expr)
#endif

// If expression is false, trigger an assertion failure using the appropriate
// method for the current platform
#define D_SP_ASSERT(expression)            \
    do {                                   \
        if (!expression)                   \
            D_SP_ASSERTFALSE(#expression); \
    } while (0)

I've thrown together a full implementation based on this on my fork of the project. It compiles, but unfortunately I don't really have a way to test it properly because I'm still trying to figure this stuff out (and I don't have a debug probe yet). Help and feedback is very much welcome.

One other point to mention: in order to support this I had to bump the C++ standard up to gnu++20. Inline assembly inside a constexpr seems to have only been added in C++20, and in Source/Utility/dsp.h there's an assert in a constexpr so that now raises a compiler error when using my proposed generic assertion macros.