Assert() с сообщением

Я видел, как где-то утверждалось, что используется с сообщением следующим образом:

assert(("message", condition));

Это работает отлично, за исключением того, что gcc выдает следующее предупреждение:

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

Как я могу остановить предупреждение?

Ответ 1

Используйте -Wno-unused-value, чтобы остановить предупреждение; (опция -Wall включает -Wunused-value).

Я думаю, что еще лучше использовать другой метод, например

assert(condition && "message");

Ответ 2

Try:

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

использовать как таковой:

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

Выполняет блок только тогда, когда assert не работает.

ВАЖНОЕ ПРИМЕЧАНИЕ: Этот метод будет оценивать выражение x дважды, в случае, если x оценивается как false! (Первый раз, когда цикл for проверяет его состояние, второй раз, когда assert оценивает переданное выражение!)

Ответ 3

Если вы хотите передать форматированное сообщение, вы можете использовать следующие макросы:

#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...

Вывод:

[ERROR] (../src/webserver.c:180: errno: адрес уже используется) [Сервер] Не удалось привязать к порту 8080: веб-сервер:.. /src/webserver.c:180: server_run: Assertion `(self- > socket = u_open (self- > port))!= -1 'не удалось.

На основе http://c.learncodethehardway.org/book/ex20.html

Ответ 4

Вы можете написать свой собственный макрос, который обеспечивает такое же использование _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 и сообщение пользователя, даже если утверждения отключены. Причина этого в том, что она не сломает программу, но предупредит, что, вероятно, будет присутствовать ошибка. Вы можете просто определить assert_msg пустым, если defined(NDEBUG), тем не менее.

Ответ 5

Согласно следующей ссылке http://www.cplusplus.com/reference/clibrary/cassert/assert/

assert ожидает только выражение. Возможно, вы используете некоторую перегруженную функцию.

В соответствии с этим допускается только выражение, и вы получаете это предупреждение.