Respostas:
Um truque que eu já vi por aí é usar o &&
operador. Como um ponteiro "é verdadeiro" se não for nulo, você pode fazer o seguinte sem alterar a condição:
assert(a == b && "A is not equal to B");
Como assert
mostra a condição que falhou, ele também exibirá sua mensagem. Se não for suficiente, você pode escrever sua própria myAssert
função ou macro que exibirá o que quiser.
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
retorna um valor diferente de zero se ele imprimiu alguma coisa, para que você possa fazer algo como assert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, embora nesse momento provavelmente deva escrever seu próprio invólucro de declaração.
Outra opção é reverter os operandos e usar o operador de vírgula. Você precisa de parênteses extras para que a vírgula não seja tratada como um delimitador entre os argumentos:
assert(("A must be equal to B", a == b));
(isso foi copiado dos comentários acima, para melhor visibilidade)
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Aqui está minha versão da macro assert, que aceita a mensagem e imprime tudo de maneira clara:
#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();
}
}
Agora você pode usar isso
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
E em caso de falha, você receberá uma mensagem como esta:
Falha na declaração: MyFunction: requer argumento não nulo
Esperado: ptr! = Nullptr
Origem: C: \ MyProject \ src.cpp, linha 22
Agradável e limpo, fique à vontade para usá-lo em seu código =)
x == y
. Em seguida, o Expr se expandirá para if( !(x == y))
e é aí que a condição será verificada, e #Expr se expandirá para a string literal "x == y"
, que depois colocamos na mensagem de erro.
BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Você pode usá-lo diretamente ou copiar o código do Boost. Observe também que a declaração Boost é apenas um cabeçalho; portanto, você pode pegar esse único arquivo se não quiser instalar todo o Boost.
Como a resposta do zneak envolve um pouco o código, uma abordagem melhor é apenas comentar o texto da string que você está falando. ou seja:
assert(a == b); // A must be equal to B
Como o leitor do erro de declaração procurará o arquivo e a linha de qualquer maneira a partir da mensagem de erro, ele verá a explicação completa aqui.
Porque, no final do dia, isso:
assert(number_of_frames != 0); // Has frames to update
lê melhor que isso:
assert(number_of_frames != 0 && "Has frames to update");
em termos de análise humana de código ou seja. legibilidade. Também não é um hack de idioma.
assert é uma combinação de macro / função. você pode definir a sua própria macro / função, usando __FILE__
, __BASE_FILE__
, __LINE__
etc, com a sua própria função que recebe uma mensagem personalizada