Respostas:
O Visual Studio define _DEBUGquando você especifica a opção /MTdou /MDd, NDEBUGdesativa as asserções C padrão. Use-os quando apropriado, ou seja, _DEBUGse você deseja que seu código de depuração seja consistente com as técnicas de depuração do MS CRT e NDEBUGse você deseja ser consistente comassert() .
Se você definir suas próprias macros de depuração (e não hackear o compilador ou o tempo de execução C), evite iniciar nomes com um sublinhado, pois eles são reservados.
O NDEBUG é padrão?
Sim, é uma macro padrão com a semântica "Sem depuração" para os padrões C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. Não há _DEBUGmacros nos padrões.
O padrão C ++ 2003 envia o leitor na "página 326" em "17.4.2.1 Cabeçalhos" para o padrão C.
Esse NDEBUG é semelhante, pois é igual à biblioteca C padrão.
Em C89 (programadores C chamaram esse padrão como padrão C) na seção "4.2 DIAGNÓSTICOS", foi dito
http://port70.net/~nsz/c/c89/c89-draft.html
Se NDEBUG for definido como um nome de macro no ponto no arquivo de origem em que está incluído, a macro assert será definida simplesmente como
#define assert(ignore) ((void)0)
Se observar o significado das _DEBUGmacros no Visual Studio
https://msdn.microsoft.com/en-us/library/b0084kay.aspx
, será visto que essa macro é definida automaticamente pela sua escolha da versão da biblioteca de tempo de execução do idioma.
Eu confio NDEBUG, porque é o único cujo comportamento é padronizado entre compiladores e implementações (consulte a documentação para a macro assert padrão). A lógica negativa é uma pequena aceleração de legibilidade, mas é um idioma comum ao qual você pode se adaptar rapidamente.
Confiar em algo como _DEBUGseria confiar em um detalhe de implementação de um determinado compilador e implementação de biblioteca. Outros compiladores podem ou não escolher a mesma convenção.
A terceira opção é definir sua própria macro para o seu projeto, o que é bastante razoável. Ter sua própria macro fornece portabilidade entre implementações e permite ativar ou desativar o código de depuração independentemente das asserções. Embora, em geral, desaconselho a existência de diferentes classes de informações de depuração habilitadas no momento da compilação, pois isso causa um aumento no número de configurações que você precisa criar (e testar) para obter benefícios indiscutivelmente pequenos.
Com qualquer uma dessas opções, se você usar código de terceiros como parte do seu projeto, precisará conhecer qual convenção ele usa.
#if !defined(NDEBUG)<- @HostileFork não é isso que você quis dizer? #ifnão #ifdef?
#ifdef NDEBUG... mas, em seguida, chame atenção especial para a lógica negativa #if !defined(NDEBUG). Caso contrário, é um pouco difícil de entender #ifndef NDEBUG"
A macro NDEBUGcontrola se as assert()instruções estão ativas ou não.
Na minha opinião, isso é separado de qualquer outra depuração - então eu uso algo diferente de NDEBUGcontrolar as informações de depuração no programa. O que eu uso varia, dependendo da estrutura com a qual estou trabalhando; sistemas diferentes têm macros ativadoras diferentes, e eu uso o que for apropriado.
Se não houver estrutura, eu usaria um nome sem um sublinhado à esquerda; esses tendem a ser reservados à 'implementação' e tento evitar problemas com colisões de nomes - duplamente quando o nome é uma macro.
#ifcódigo controlado na outra. assert(huge_object.IsValid());pode ser lento enquanto assert(ptr != nullptr);provavelmente não é. Concordo com Jonathan que o log e o rastreamento devem provavelmente ser diferentes das asserções, pelo menos em projetos maiores, mas não penso em log ou rastreamento como código de depuração, e foi por isso que pedi esclarecimentos.
Infelizmente DEBUGestá sobrecarregado. Por exemplo, é recomendável sempre gerar e salvar um arquivo pdb para compilações RELEASE. O que significa uma das opções de -Zxsinalizador e -DEBUGvinculador. Embora _DEBUGesteja relacionado a versões especiais de depuração da biblioteca de tempo de execução, como chamadas para malloce free. Em seguida NDEBUG, desabilitará as asserções.