带消息的断言()

发布于 2024-11-04 21:51:16 字数 220 浏览 6 评论 0原文

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

assert(("message", condition));

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

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

如何停止警告?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

゛时过境迁 2024-11-11 21:51:16

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

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

assert(condition && "message");

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");
仅此而已 2024-11-11 21:51:16

Try:

#define assert__(x) for ( ; !(x) ; assert(x) )

这样使用:

assert__(x) {
    printf("assertion will fail\n"); 
}

仅当断言失败时才会执行该块。

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


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 case x evaluates to false! (First time, when the for loop is checking its condition; second time, when the assert is evaluating the passed expression!)

吃不饱 2024-11-11 21:51:16

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

#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); }

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

输出:

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

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

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

末が日狂欢 2024-11-11 21:51:16

按照传统,(void) 会向编译器传达您故意忽略表达式的信息:

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

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!");
∞梦里开花 2024-11-11 21:51:16

我喜欢在 C 中这样做。这允许通过以下方式调用 assert

assert(expression);
assert(expression, "reason");
assert(file, "cannot open %s", filename);

以下是代码:

#define assert(cond, ...) \
  if (!(cond)) \
    _assert(#cond, __FILE__, __LINE__, #__VA_ARGS__ __VA_OPT__(,) ##__VA_ARGS__)

void _assert (const char* snippet, const char* file, int line, const char* message, ...)
{
  print("assert failed %s:%d %s\n", file, line, snippet);
 
  if (*message)
  {
    va_list arg;
    va_start(arg, message);
    char* data = va_arg(arg, char*);
    vprintf(data, arg);
  }
}

I like to do it this way in C. This allows calling assert the following ways:

assert(expression);
assert(expression, "reason");
assert(file, "cannot open %s", filename);

Here is the code:

#define assert(cond, ...) \
  if (!(cond)) \
    _assert(#cond, __FILE__, __LINE__, #__VA_ARGS__ __VA_OPT__(,) ##__VA_ARGS__)

void _assert (const char* snippet, const char* file, int line, const char* message, ...)
{
  print("assert failed %s:%d %s\n", file, line, snippet);
 
  if (*message)
  {
    va_list arg;
    va_start(arg, message);
    char* data = va_arg(arg, char*);
    vprintf(data, arg);
  }
}
星軌x 2024-11-11 21:51:16

对于意外的开关默认情况,选项是

assert(!"message");

For unexpected default case of a switch, an options is

assert(!"message");
洒一地阳光 2024-11-11 21:51:16

接受 const char* 并返回 true 的函数可能会让您免受各种警告:

#include <assert.h>

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

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

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

#include <assert.h>

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

#define assert_msg(expr, msg) assert((expr) && always_true(msg))
枕头说它不想醒 2024-11-11 21:51:16

就我而言,我更改了 @pmg 的答案以便能够控制输出。 (... && "message") 对我不起作用。

#include <assert.h>
#include <stdio.h>

#define __DEBUG__ 1

assert ((1 == 1) && 
       (__DEBUG__ && printf("  - debug: check, ok.\n")) || !__DEBUG__);

In my case, I changed @pmg's answer to be able to control the output. The (... && "message") didn't work for me.

#include <assert.h>
#include <stdio.h>

#define __DEBUG__ 1

assert ((1 == 1) && 
       (__DEBUG__ && printf("  - debug: check, ok.\n")) || !__DEBUG__);
枫以 2024-11-11 21:51:16

您可以编写自己的宏来提供与 _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

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

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.

琉璃繁缕 2024-11-11 21:51:16

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

断言只需要表达式。可能您正在使用一些重载函数。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文