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 assertmostra a condição que falhou, ele também exibirá sua mensagem. Se não for suficiente, você pode escrever sua própria myAssertfunção ou macro que exibirá o que quiser.
Outra opção é reverter os operandos e usar o operador de vírgula. Você precisa parênteses extras para que a vírgula não é tratado como um delimitador entre os argumentos:assert(("A must be equal to B", a == b));
Keith Thompson
3
Seria bom, no entanto, ser capaz de imprimir os valores das variáveis, como em: #assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
31313 de Frank
7
@Frank, printfretorna 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.
zneak
1
Código ruim! Eu não entendo isso! Se a == b for falso, a expressão -e também deve ser falsa e, portanto, a cadeia de caracteres não deve ser avaliada.
Ragnarius 7/11
1
@TUIlover, não é assim que os literais de string C funcionam; são constantes em tempo de compilação e seu uso nesse contexto é trivialmente otimizado. Não há custo de tempo de execução.
Zneak 9/08/19
45
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)
Esta é uma grande aproximação, com uma questão pequena, ele irá mostrar "aviso: operando esquerdo do operador vírgula não tem efeito" quando compilado em g ++ com `valor -Wunused
v010dya
1
ou com uma macro: #ifndef m_assert #define m_assert (expr, msg) assert ((msg, expr)) #endif
Szymon Marczak
O uso de um wrapper de macro permite evitar o aviso do gcc:#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Jander 24/09
25
Aqui está minha versão da macro assert, que aceita a mensagem e imprime tudo de maneira clara:
Estou um pouco confuso. O #Expr é tratado como uma string para substituição direta? Qual é a diferença entre #Expr e Expr?
Minh Tran
@MinhTran Vamos supor que sua condição de afirmação seja 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.
Eugene Magdalits 14/10
Infelizmente, esta solução causa um comportamento indefinido devido ao uso de identificadores reservados.
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.
@Jichao, o que você quer dizer com implementar a interface assert?
Tarc 22/08/16
7
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.
"Como o leitor do erro de declaração procurará o arquivo e a linha de qualquer maneira a partir da mensagem de erro", somente se for diligente.
Jason S
Somente se eles querem consertar o erro, você quer dizer ... que comentário bobo
metamorfose
1
Não. Quanto mais fácil você entender o problema, maior a probabilidade de que elas tomem medidas.
Jason S
encolher de ombros Discordo.
metamorfose
2
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
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:Como
assert
mostra a condição que falhou, ele também exibirá sua mensagem. Se não for suficiente, você pode escrever sua própriamyAssert
função ou macro que exibirá o que quiser.fonte
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 comoassert(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:
(isso foi copiado dos comentários acima, para melhor visibilidade)
fonte
#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:
Agora você pode usar isso
E em caso de falha, você receberá uma mensagem como esta:
Agradável e limpo, fique à vontade para usá-lo em seu código =)
fonte
x == y
. Em seguida, o Expr se expandirá paraif( !(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.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.
fonte
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:
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:
lê melhor que isso:
em termos de análise humana de código ou seja. legibilidade. Também não é um hack de idioma.
fonte
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 personalizadafonte
Para vc, adicione o seguinte código em assert.h,
fonte