Use standard ASSERT/Q_ASSERT, but beware of "invalid" assertions, especially if you leave such diagnostics in external testing (build without NDEBUG).
Small story regarding DBC implementation (using assertions) in a C++ project and "debugging always enabled" policy.
We were using pretty standard tools (ASSERT()/Q_ASSERT()) as DBC implementation until we hit the following situation in integration testing: our latest build was always failing just after start. It was not very professional to release such version (after week of internal QA efforts).
How the problem was introduced?
- A developer left wrong assertion (invalid logic expression) in source code
- All our pre-release builds had assertions enabled (to track errors in integration tests)
- Internal QA has different environment settings than integration tests, so the "assertion error" was not visible
As a result poor developer was blamed for this error (obviously without this ASSERT there would be no crash) and we had to release hotfix to allow integration tests to be continued.
First of all: I need assertions enabled in integration tests to track failed conditions (the more assertions the better), on the other hand I don't want developers to be afraid that some "extra" ASSERT will crash full software stack.
I found, probably interesting C++-based resolution for this problem: weak asserions. The idea is to not stop whole application on failed assertion, but to record stacktrace for later analysis and continue. We can check as many expectations as we like without fear of crash and we get feedback (stacktraces) from integration. Single process run can provide many failed assertion cases for analysis instead of only one (because there's no abort() called).
Implementation of this idea (using some LD_PRELOAD magic) is shortly described here: http://blog.aplikacja.info/2011/10/assert-to-abort-or-not-to-abort-thats-the-question/