assert()与消息

Ale*_*dru 39 c gcc assert compiler-warnings

我通过以下方式看到某处断言与消息一起使用:

assert(("message", condition));
Run Code Online (Sandbox Code Playgroud)

这似乎很有效,除了gcc抛出以下警告:

warning: left-hand operand of comma expression has no effect
Run Code Online (Sandbox Code Playgroud)

我怎么能停止警告?

pmg*_*pmg 68

使用-Wno-unused-value停止警告; (选项-Wall包括-Wunused-value).

我认为更好的是使用另一种方法,比如

assert(condition && "message");
Run Code Online (Sandbox Code Playgroud)

  • 好的,我通常做断言(条件/*消息*/). (7认同)

小智 21

尝试:

#define assert__(x) for ( ; !(x) ; assert(x) )
Run Code Online (Sandbox Code Playgroud)

使用如下:

assert__(x) {
    printf("assertion will fail\n"); 
}
Run Code Online (Sandbox Code Playgroud)

只有在断言失败时才会执行该块.

重要说明:此方法将评估表达式x两次,以防x评估为false!(第一次,当for循环检查其条件时;第二次,当assert评估传递的表达式时!)

  • 关于这个的好处是你可以通过使用`assert __(foo);`来省略消息,并且分号将结束块. (3认同)
  • 如果`(x)`只返回一次true,这样的实现将不起作用:`string("a") a; 断言__(a.append("b") == "ab") { ... }` (2认同)
  • 为什么是“for”而不是“if”? (2认同)

frm*_*ryr 12

如果要传递格式化消息,可以使用以下宏:

#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); }
Run Code Online (Sandbox Code Playgroud)

然后像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...
Run Code Online (Sandbox Code Playgroud)

输出:

[错误](../src/webserver.c:180:错误:地址已在使用中)[服务器]无法绑定到端口8080:webserver:../ src/webserver.c:180:server_run:断言`( self-> socket = u_open(self-> port))!= -1'失败.

基于http://c.learncodethehardway.org/book/ex20.html