assert() with message
Solution 1
Use -Wno-unused-value
to stop the warning; (the option -Wall
includes -Wunused-value
).
I think even better is to use another method, like
assert(condition && "message");
Solution 2
Try:
#define assert__(x) for ( ; !(x) ; assert(x) )
use as such:
assert__(x) {
printf("assertion will fail\n");
}
Will execute the block only when assert fails.
IMPORTANT NOTE: This method will evaluate expression
x
twice, in casex
evaluates tofalse
! (First time, when thefor
loop is checking its condition; second time, when theassert
is evaluating the passed expression!)
Solution 3
If you want to pass a formatted message, you could use the following macros:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_error(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define assertf(A, M, ...) if(!(A)) {log_error(M, ##__VA_ARGS__); assert(A); }
Then use it like printf:
// With no args
assertf(self != NULL,"[Server] Failed to create server.");
// With formatting args
assertf((self->socket = u_open(self->port)) != -1,"[Server] Failed to bind to port %i:",self->port);
// etc...
Output:
[ERROR] (../src/webserver.c:180: errno: Address already in use) [Server] Failed to bind to port 8080: webserver: ../src/webserver.c:180: server_run: Assertion `(self->socket = u_open(self->port)) != -1' failed.
Based on http://c.learncodethehardway.org/book/ex20.html
Solution 4
By tradition, (void)
communicates to the compiler that you are knowingly ignoring an expression:
/* picard.c, TNG S6E11. */
#define assertmsg(x, msg) assert(((void) msg, x))
assertmsg(2+2==5, "There! are! four! lights!");
Solution 5
For unexpected default case of a switch, an options is
assert(!"message");
Comments
-
Alexandru almost 3 years
I saw somewhere assert used with a message in the following way:
assert(("message", condition));
This seems to work great, except that gcc throws the following warning:
warning: left-hand operand of comma expression has no effect
How can I stop the warning?
-
pmg about 13 yearsThe inner parenthesis make it ok:
assert( ("message", condition) );
This is C: no overloading. -
Lightness Races in Orbit over 11 yearsDon't see what relevance a C++ website has to a C question.
-
Julien over 11 yearsNice one, I usually do assert(condition /* message */).
-
Samaursa about 11 yearsThis sometimes gives "Conditional expression is constant" warning in Visual Studio. Any ideas on how to remove the warning without suppressing it?
-
pmg about 11 years@Samaursa: you probably have an issue with plain
condition
. Does the compiler also warn with justassert(condition);
? -
Samaursa about 11 yearsIt does not. The interesting thing is that OP's original problem code is the solution to VS's warnings!
assert((Msg, Cond));
works without warnings on VS 2008. -
Kevin Cox almost 10 yearsThe nice thing about this is that you can omit the message if you want by using
assert__(foo);
and the semicolon will end the block. -
chad over 8 yearsThis, unfortunately, isn't portable. C99 requires that you use at least one of the optional arguments in a variadic macro (e.g this:
assertf(x == y, "x does not equal y")
violates the standard. This is easily rectified viaassertf(x == y, "%s", "x does not equal y")
however). It also relies on the gcc extension##__VA_ARGS__
which isn't necessarily a bad thing, but it does make it less portable -
Oleg over 8 yearsSuch implementation will not work if
(x)
returns true only once:string("a") a; assert__(a.append("b") == "ab") { ... }
-
Caridorc over 8 yearsWhy
for
and notif
? -
ahogen over 4 years
assert((<cond>) && "msg");
causes CppCheck (v1.90) to generate an "incorrectStringBooleanError" warning. -
VLL almost 3 yearsThis seems to be always false. Where is the condition that is being tested?
-
VLL almost 3 yearsThis does not seem to work in GCC. Failing
assert
stops the program execution andprintf
is not called. -
Flaviu almost 3 yearsThis useful for unexpected default case of a switch.
-
john-g almost 3 yearsThat, while true, doesn't have anything to do with the original question.
-
Jack G over 2 years@vil It is not possible for
assert
to stop the program beforeprintf
becauseassert
is not called until afterprintf
.