Есть ли способ добавить или отредактировать сообщение, созданное assert? Я бы хотел использовать что-то вроде
assert(a == b, "A must be equal to B");
Затем компилятор добавляет строку , время и так далее ...
Является ли это возможным?
Есть ли способ добавить или отредактировать сообщение, созданное assert? Я бы хотел использовать что-то вроде
assert(a == b, "A must be equal to B");
Затем компилятор добавляет строку , время и так далее ...
Является ли это возможным?
Ответы:
Хакер, который я видел, - это использование &&
оператора. Поскольку указатель "истинен", если он не равен нулю, вы можете сделать следующее, не изменяя условия:
assert(a == b && "A is not equal to B");
Поскольку assert
показывает условие, которое не удалось, оно также отобразит ваше сообщение. Если этого недостаточно, вы можете написать свою собственную myAssert
функцию или макрос, который будет отображать все, что вы хотите.
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
возвращает ненулевое значение, если он что-то напечатал, поэтому вы могли бы сделать что-то подобное assert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, хотя в этот момент вам, вероятно, следует написать свою собственную оболочку assert.
Другой вариант - поменять местами операнды и использовать оператор запятой. Вам нужны дополнительные круглые скобки, чтобы запятая не рассматривалась как разделитель между аргументами:
assert(("A must be equal to B", a == b));
(это было скопировано из приведенных выше комментариев для лучшей видимости)
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Вот моя версия макроса 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
Красиво и чисто, смело используйте его в своем коде =)
x == y
. Затем Expr будет расширяться, if( !(x == y))
и здесь проверяется условие, а #Expr расширяется в строковый литерал "x == y"
, который мы затем помещаем в сообщение об ошибке.
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Вы можете использовать это напрямую или скопировать код Boost. Также обратите внимание, что утверждение Boost - это только заголовок, поэтому вы можете просто получить этот единственный файл, если не хотите устанавливать все Boost.
Поскольку ответ zneak несколько запутывает код, лучший подход - просто прокомментировать текст строки, о котором вы говорите. т.е. .:
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");
с точки зрения человеческого анализа кода, т.е. читаемость. Также не языковой взлом.
assert - это комбинация макроса / функции. вы можете определить свой собственный макрос / функцию, используя __FILE__
, __BASE_FILE__
и __LINE__
т. д., со своей собственной функцией, которая принимает настраиваемое сообщение