Добавить пользовательские сообщения в assert? - PullRequest
107 голосов
/ 12 сентября 2010

Есть ли способ добавить или отредактировать сообщение, выданное assert? Я хотел бы использовать что-то вроде

assert(a == b, "A must be equal to B");

Затем компилятор добавляет строку , время и так далее ...

Возможно ли это?

Ответы [ 8 ]

201 голосов
/ 12 сентября 2010

Взлом, который я видел вокруг, это использование оператора &&. Поскольку указатель «true», если он не равен NULL, вы можете сделать следующее, не изменяя условие:

assert(a == b && "A is not equal to B");

Поскольку assert показывает условие, которое не удалось, оно также будет отображать ваше сообщение. Если этого недостаточно, вы можете написать свою собственную myAssert функцию или макрос, который будет отображать все, что вы хотите.

35 голосов
/ 16 июля 2012

Другой вариант - поменять местами операнды и использовать оператор запятой.Вам нужны дополнительные скобки, чтобы запятая не рассматривалась как разделитель между аргументами:

assert(("A must be equal to B", a == b));

(это было скопировано из приведенных выше комментариев, для лучшей наглядности)

19 голосов
/ 17 мая 2016

Вот моя версия макроса assert, который принимает сообщение и распечатывает все ясно:

#include <iostream>

#ifndef NDEBUG
#   define M_Assert(Expr, Msg) \
    __M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
#   define M_Assert(Expr, Msg) ;
#endif

void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
    if (!expr)
    {
        std::cerr << "Assert failed:\t" << msg << "\n"
            << "Expected:\t" << expr_str << "\n"
            << "Source:\t\t" << file << ", line " << line << "\n";
        abort();
    }
}

Теперь вы можете использовать это

M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");

И в случае неудачи вы получите сообщение, подобное этому:

Ошибка подтверждения: MyFunction: требуется ненулевой аргумент

Ожидается: ptr! = Nullptr

Источник: C: \ MyProject \ src.cpp, строка 22 * ​​1014 *

Красиво и чисто, не стесняйтесь использовать его в своем коде =)

18 голосов
/ 09 октября 2012
BOOST_ASSERT_MSG(expre, msg)

http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html

Вы можете использовать это непосредственно или скопировать код Boost.Также обратите внимание, что Boost assert является только заголовком, так что вы можете просто взять этот единственный файл, если вы не хотите устанавливать все Boost.

7 голосов
/ 18 ноября 2014

Поскольку ответ zneak несколько усложняет код, лучшим подходом будет просто комментировать текст строки, о которой вы говорите. ie.:

assert(a == b); // A must be equal to B

Так как читатель ошибки assert будет искать файл и строку в любом случае из сообщения об ошибке, он увидит полное объяснение здесь.

Потому что в конце дня это:

assert(number_of_frames != 0); // Has frames to update

читается лучше, чем это:

assert(number_of_frames != 0 && "Has frames to update");

с точки зрения человеческого анализа кода, т.е. читаемость. Также не языковой взлом.

1 голос
/ 12 сентября 2010

assert - комбинация макросов / функций. вы можете определить свой собственный макрос / функцию, используя __FILE__, __BASE_FILE__, __LINE__ и т. д., с вашей собственной функцией, которая принимает пользовательское сообщение

0 голосов
/ 04 августа 2015

Почему никто не упомянул самое чистое решение?

bool AMustBeEqualToB = (a == b);
assert(AMustBeEqualToB);
0 голосов
/ 22 октября 2013

Для vc, добавьте следующий код в assert.h,

#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )
...