Pergunta

Por isso, quero dizer, o que eu preciso fazer para ter afirmações úteis no meu código?

MFC é muito fácil, eu só uso ASSERT (algo).

O que é a maneira não-MFC?

Editar: É possível parar assert quebrando em assert.c em vez de que o meu arquivo que chamou assert ()

?

Editar:? Qual é a diferença entre <assert.h> & <cassert>

resposta aceita: Cargas de grandes respostas deste post, eu gostaria de poder aceitar mais de uma resposta (ou alguém iria combinar todos eles). Então resposta fica atribuído a Ferruccio (para primeira resposta).

Foi útil?

Solução

#include <cassert>

assert(something);

e para a verificação em tempo de compilação, estática do impulso afirma são muito úteis:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) == 4);  // compile fails if ints aren't 32-bit

Outras dicas

Isso depende se ou não você está procurando algo que funciona fora do Visual C ++. Também depende de que tipo de afirmação que você está procurando.

Existem alguns tipos de afirmações:

  1. Preprocessor
    Estas afirmações são feitas usando o pré-processador diretiva #error
    afirmações de pré-processamento só são avaliadas durante a fase de pré-processamento e, portanto, não são úteis para coisas como modelos.

  2. Executar Tempo
    Estas afirmações são feitas usando a função assert() definido no <cassert>
    Executar tempo afirmações são avaliados somente em tempo de execução. E como BoltBait apontou, não são compilados em se a macro NDEBUG foi definido.

  3. estático
    Estas afirmações são feitas, como você disse, usando a macro ASSERT(), mas só se você estiver usando o MFC. Eu não sei de uma outra maneira de fazer afirmações estáticas que faz parte da / C ++ padrão, no entanto, a biblioteca do impulso oferece outra solução C:. static_assert
    A função static_assert da biblioteca Boost é algo que vai ser adicionados no padrão C ++ 0x .

Como uma advertência adicional, a função assert() que Ferruccio sugeriu não tem o mesmo comportamento que o ASSERT() macro MFC. O primeiro é uma afirmação tempo executar, enquanto a posterior é uma afirmação estática.

Espero que isso ajude!

Assert é (geralmente) Debug Só

O problema com "assert" é que é geralmente em binários de depuração, e que alguns desenvolvedores usá-los como se o código ainda estaria em produção.

Isto não é mau em si, como o código é suposto ser intensivamente testado e, portanto, os erros que produzem a assert certamente serão descobertos, e removido.

Mas, às vezes (na maioria das vezes?), Os testes não são tão intensa como queria. Eu não vou falar de um trabalho antigo, onde tivemos de código até o último minuto ( não pede ... Às vezes, os gestores são apenas ... Aham ... ) ... Qual é o ponto de uma declaração está adicionando a um código que será compilado e entregue como um binário lançamento para o cliente no minuto seguinte?

Assert em (alguns) aplicações da vida real

Em nossa equipe, precisávamos de algo para detectar o erro, e ao mesmo tempo algo mais para lidar com o erro. E foi necessário, potencialmente, na compilação de lançamento.

Assert irá detectar e tratar o erro apenas em compilação de depuração.

Por isso, acrescentou, em vez de uma macro XXX_ASSERT, bem como uma macro XXX_RAISE_ERROR.

A macro XXX_ASSERT faria a mesma coisa que a macro ASSERT, mas seria construído tanto em Debug e Release. Seu comportamento (Escreva um log, abra um messagebox, não fazer nada, etc.) pode ser controlado por um arquivo de inicialização, e então, ele iria abortar / sair do aplicativo.

Este foi usado como:

bool doSomething(MyObject * p)
{
   // If p is NULL, then the app will abort/exit
   XXX_ASSERT((p != NULL), "Hey ! p is NULL !") ;

   // etc.
}

XXX_RAISE_ERROR macro seria apenas "log" o erro, mas não iria tentar lidar com isso. Isso significa que ele poderia registrar a mensagem em um arquivo e / ou abrir um MessageBox com a mensagem, e um botão para continuar, e outro para lançar uma sessão de depuração (como por ini arquivo de configuração). Este foi usado como:

bool doSomething(MyObject * p)
{
   if(p == NULL)
   {
      // First, XXX_RAISE_ERROR will alert the user as configured in the INI file
      // perhaps even offering to open a debug session
      XXX_RAISE_ERROR("Hey ! p is NULL !") ;
      // here, you can handle the error as you wish
      // Than means allocating p, or throwing an exception, or
      // returning false, etc.
      // Whereas the XXX_ASSERT could simply crash.
   }

   // etc.
}

Um ano após a sua introdução nos nossos libs, única XXX_RAISE_ERROR está sendo usado. Claro, ele não pode ser usado em partes de tempo crítico do aplicativo (temos um XXX_RAISE_ERROR_DBG para isso), mas em qualquer outro lugar, é bom. E os fatos que se pode usar qualquer que seja preferido o tratamento de erros, e que ele pode ser ativado à vontade, seja no computador programador, ou o testador, ou mesmo o usuário, é bastante útil.

Para responder à pergunta em sua segunda "editar":

é o cabeçalho C

é o cabeçalho biblioteca padrão C ++ ... é normalmente inclui

Para quebrar dentro do arquivo que chamou o assert, você pode usar uma macro personalizada que gera uma exceção ou chamadas __debugbreak:

#define MYASSERT(EXPR, MSG) if (!(EXPR)) throw MSG;

Ou:

#define MYASSERT(EXPR) if (!(EXPR)) __debugbreak();

Assert Básico Uso

#include <cassert>

/* Some code later */
assert( true );

Melhores Notas Práticas

afirma são usados ??para identificar estados de tempo de execução que devem ser true . Como resultado, eles são compilados em modo de versão.

Se você tem uma situação onde você quer uma declaração para sempre acertar, você pode passar falsa a ele. Por exemplo:

switch ( someVal ):
{
case 0:
case 1:
  break;
default:
  assert( false ); /* should never happen */
}

Também é possível passar uma mensagem através assert:

assert( !"This assert will always hit." );

Mature bases de código frequentemente estender a funcionalidade assert. Algumas das extensões comuns incluem:

  • Alternando afirma em uma base per-módulo para teste Localize.
  • Criar uma macro assert adicional que é compilado em mais compilações de depuração. Isso é desejável para o código que é chamado com muita freqüência (milhões de vezes por segundo) e é improvável que seja incorreto.
  • Permitindo que os usuários desativar o assert actualmente atingido, todos afirma na unidade de compilação ou todas afirma na base de código. Isso interrompe benigna afirma de ser acionado, criando inutilizável constrói.

Microsoft específicos de CRT afirma

#include <crtdbg.h>
#include <sstream>
...
// displays nondescript message box when x <= 42
_ASSERT(x > 42);
// displays message box with "x > 42" message when x <= 42
_ASSERTE(x > 42);
// displays message box with computed message "x is ...!" when x <= 42
_ASSERT_EXPR(
   x > 42, (std::stringstream() << L"x is " << x << L"!").str().c_str());

Há uma biblioteca de código aberto mais avançado chamado ModAssert, que tem afirmações que os trabalhos sobre o Visual C ++ e gcc. Provavelmente também em outros compiladores, não sei com certeza. Leva algum tempo para aprendê-la, mas se você quer bons afirmações que não dependem de MFC, olhar para estes. É em http://sourceforge.net/projects/modassert/

uso intellisense para abri-lo no visual studio (clique direito)

// cassert standard header
#include <yvals.h>
#include <assert.h>

yvals.h é coisa janelas. assim, tanto quanto assert () em si está em causa, as duas maneiras de incluí-lo são idênticas. é uma boa prática para usar o <cxxx> porque muitas vezes não é tão simples (embrulho namespace e talvez outra mágica)

Isso quebra no local chamador para mim ...

aqui está um href="http://powerof2games.com/node/10" rel="nofollow artigo explicando por que você não quer escrever este macro-se.

Aqui está o meu iteração mais recente de uma instalação de declaração na C ++: http://pempek.net/articles/2013/11/17/cross-platform-cpp-assertion-library/

É um drop-in 2 arquivos lib você pode facilmente adicionar ao seu projeto.

Para responder à consulente é terceira questão: a primeira razão que nós usamos "cassert" em vez de "assert.h" é porque, no caso do C ++, há um subsídio feito para o fato de que o compilador C ++ pode não armazenar as descrições de funções em arquivos de código, mas de uma dll ou no próprio compilador. O segundo é que pode haver pequenas mudanças feitas às funções, a fim de facilitar as diferenças entre C e C ++, seja presente ou no futuro. Porque assert.h é uma biblioteca C, a preferência é usar "cassert", enquanto no C ++.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top