assert() function working principle in C for me is like a dark forest. according to this answer here https://stackoverflow.com/a/1571360, you can use the following construction to output the custom message to your assertion: assert(retval == 1 && “retval is false”);
, so how does assert know that the expression with just a binary and actually contains a message and that it is not the part of the expression itself, and, also, which precompiler directives it uses in order to reveal the error's origin?
how does assert know that the expression with just a binary and actually contains a message and that it is not the part of the expression itself?
Operator #
replaces the parameter of a macro by it's string representation.
#define TOSTRING(parameter) #parameter
// ^^^^^^^^^ - always followed by a macro parameter
// ^ - # operator
const char *a = TOSTRING(almost anything does not matter !@#$%^&*./;[]);
// expands to:
// const char *a = "almost anything does not matter !@#$%^&*./;[]";
Using that operator, you can take the input from a macro and pass it to your function as a string:
#define myassert(expression) myassert_handle(expression, #expression)
void myassert_handle(bool expression_result, const char *exprsesion_string) {
if (expression_result == false) {
fprintf(stderr, "Och no: expression %s failed!\n", exprsesion_string);
abort();
}
}
That way:
myassert(retval == 1 && "retval is false");
// expands to
myassert_handle(retval == 1 && "retval is false", "retval == 1 && \"retval is false\"");
// and if the expression will fail, it will print:
// Och no: expression retval == 1 && "retval is false" failed!
Assert macro also uses __FILE__
and __LINE__
predefined macros and __func__
to print a nice looking message where the assertion failed. And assert is usually implemented with conditional operator so that compiler can optimize it better.