C语言 assert() 带消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5867834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:33:25  来源:igfitidea点击:

assert() with message

cgcccompiler-warningsassert

提问by Alexandru

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:

这似乎很好用,除了 gcc 抛出以下警告:

warning: left-hand operand of comma expression has no effect

How can I stop the warning?

我怎样才能停止警告?

回答by pmg

Use -Wno-unused-valueto stop the warning; (the option -Wallincludes -Wunused-value).

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

I think even better is to use another method, like

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

assert(condition && "message");

回答by bugfeeder

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 xtwice, in case xevaluates to false! (First time, when the forloop is checking its condition; second time, when the assertis evaluating the passed expression!)

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

回答by frmdstryr

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:

然后像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.

[ERROR] (../src/webserver.c:180: errno: Address already in use) [Server] 无法绑定到端口 8080: webserver: ../src/webserver.c:180: server_run: Assertion `( self->socket = u_open(self->port)) != -1' 失败。

Based on http://c.learncodethehardway.org/book/ex20.html

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

回答by Cacahuete Frito

You could write your own macro that provides the same usage of _Static_assert(expr, msg):

您可以编写自己的宏来提供相同的用法_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_msgto be empty if defined(NDEBUG), though.

我还有一个宏warn_bug(),即使断言被禁用,它也会打印程序的名称、文件、行、函数、errno 值和字符串以及用户消息。其背后的原因是它不会破坏程序,但会警告可能存在错误。但是,您可以assert_msg将 if定义为空defined(NDEBUG)

回答by Arthur2e5

By tradition, (void)communicates to the compiler that you are knowingly ignoring an expression:

按照传统,(void)向编译器传达您有意忽略表达式:

/* picard.c, TNG S6E11. */
#define assertmsg(x, msg) assert(((void) msg, x))
assertmsg(2+2==5, "There! are! four! lights!");

回答by JiaHao Xu

A function that takes const char*and returns truewould probably save you from all sorts of warnings:

一个接受const char*和返回的函数true可能会让你免于各种警告:

#include <assert.h>

int always_true(const char *msg) {
    return 1;
}

#define assert_msg(expr, msg) assert((expr) && always_true(msg))

回答by Dhiraj

According to following link http://www.cplusplus.com/reference/clibrary/cassert/assert/

根据以下链接 http://www.cplusplus.com/reference/clibrary/cassert/assert/

assert is expecting only expression. May be you are using some overloaded function.

assert 只期待表达。可能是您正在使用某些重载函数。

According to this, only expression is allowed and thus you are getting this warning.

据此,只允许表达,因此您会收到此警告。