Единственный способ получить номер строки, файл и текстовую версию - через макрос. Тем не менее:
#include <assert.h>
class debug
{
public:
static void my_assert(bool passed, const char* assert, const char* file, long line)
{
if (passed == false)
std::cout<<"failed assert "<<assert<<" in "<<file<<" at "<<line<<".\n";
}
#ifdef NDEBUG
#define myassert(x) my_assert(true, "", "", 0)
#else
#define myassert(x) my_assert(x, #x , __FILE__, __LINE__ )
#endif
};
int main() {
debug::myassert(sizeof(int)==4);
return 0,
}
Этот код работает странным образом. Первое x
- это само выражение assert, которое оценивается как true или false, чтобы сказать my_assert, что делать. #x
- волшебная команда препроцессора, которая делает версию x
для char *, поэтому мы можем ее отобразить. __FILE__
заменяется именем файла, а __LINE__
заменяется номером строки. (Поскольку это макрос, он имеет тот же номер строки, что и вызывающая функция).
Когда вы набираете debug::myassert(sizeof(int)==4);
, препроцессор говорит: «Я знаю, что такое myassert(whatever)
!» и заменяет его. Таким образом, он заменяет все это на: debug::my_assert(sizeof(int)==4, "sizeof(int)==4", "main.cpp", 27);
, которая является допустимой строкой кода. Так, например, если sizeof (int) равен 8 (это на некоторых машинах), первый параметр - false
, и строка отображается как «fail assert sizeof (int) == 4 в main.cpp на 27».