Is it evil to redefine assert? Is it evil to redefine assert? c c

Is it evil to redefine assert?


Redefining a Standard macro is an ugly idea, and you can be sure the behaviour's technically undefined, but in the end macros are just source code substitutions and it's hard to see how it could cause problems, as long as the assertion causes your program to exit.

That said, your intended substitution may not be reliably used if any code in the translation unit after your definition itself redefines assert, which suggests a need for a specific order of includes etc. - damned fragile.

If your assert substitutes code that doesn't exit, you open up new problems. There are pathological edge cases where your ideas about throwing instead could fail, such as:

int f(int n){    try    {        assert(n != 0);        call_some_library_that_might_throw(n);    }    catch (...)    {        // ignore errors...    }    return 12 / n;}

Above, a value of 0 for n starts crashing the application instead of stopping it with a sane error message: any explanation in the thrown message won't be seen.

I am with Andrei Alexandresciu in thinking that exceptions are the best known method to report errors in code that wants to be secure. (Because the programmer cannot forget to check an error return code.)

I don't recall Andrei saying quite that - do you have a quote? He's certainly thought very carefully about how to create objects that encourage reliable exception handling, but I've never heard/seen him suggest that a stop-the-program assert is inappropriate in certain cases. Assertions are a normal way of enforcing invariants - there's definitely a line to be drawn concerning which potential assertions can be continued from and which can't, but on one side of that line assertions continue to be useful.

The choice between returning an error value and using exceptions is the traditional ground for the kind of argument/preference you mention, as they're more legitimately alternatives.

If this is right ... if there is a phase change in error reporting, from exit(1)/signals/ to exceptions ... one still has the question of how to live with the legacy code.

As above, you shouldn't try to migrate all existing exit() / assert etc. to exceptions. In many cases, there will be no way to meaningfully continue processing, and throwing an exception just creates doubt about whether the issue will be recorded properly and lead to the intended termination.

And, overall - there are several error reporting schemes. If different libraries use different schemes, how make them live together.

Where that becomes a real issue, you'd generally select one approach and wrap the non-conforming libraries with a layer that provides the error handling you like.


I wrote an application that runs on an embedded system. In the early days I sprinkled asserts through the code liberally, ostensibly to document conditions in the code that should be impossible (but in a few places as lazy error-checking).

It turned out that the asserts were occasionally being hit, but no one ever got to see the message output to the console containing the file and line number, because the console serial port generally was not connected to anything. I later redefined the assert macro so that instead of outputting a message to the console it would send a message over the network to the error logger.

Whether or not you think redefining assert is 'evil', this works well for us.


If you include any headers/libraries that utilize assert, then you would experience unexpected behavior, otherwise the compiler allows you to do it so you can do it.

My suggestion, which is based on personal opinion is that in any case you can define your own assert without the need to redefine the existing one. You are never gaining extra benefit from redefining the existing one over defining a new one with a new name.