问题
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?
回答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");
回答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!)
回答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
回答4:
You could write your own macro that provides the same usage of _Static_assert(expr, msg)
:
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
/*
* void assert_msg(bool expr, const char *msg);
*/
#if !defined(NDEBUG)
#define assert_msg(expr, msg) do \
{ \
const bool e_ = expr; \
\
if (!e_) { \
fputs(msg, stderr); \
fputc('\n', stderr); \
assert(e_); \
} \
} while (0)
#else
#define assert_msg(expr, msg) do \
{ \
\
if (!(expr)) \
warn_bug(msg); \
} while (0)
#endif
I also have a macro warn_bug()
that prints the name of the program, the file, the line, the function, the errno value and string, and a user message, even if asserts are disabled. The reason behind it is that it won't break the program, but it will warn that a bug will probably be present. You could just define assert_msg
to be empty if defined(NDEBUG)
, though.
回答5:
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!");
回答6:
According to following link http://www.cplusplus.com/reference/clibrary/cassert/assert/
assert is expecting only expression. May be you are using some overloaded function.
According to this, only expression is allowed and thus you are getting this warning.
来源:https://stackoverflow.com/questions/5867834/assert-with-message