Qual definição de pré-processador deve ser usada para especificar seções de depuração do código?
Use #ifdef _DEBUG
ou #ifndef NDEBUG
ou existe uma maneira melhor de fazê-lo, por exemplo #define MY_DEBUG
?
Eu acho que _DEBUG
é específico do Visual Studio, é o padrão NDEBUG?
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á
_DEBUG
macros 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.
Em C89 (programadores C chamaram esse padrão como padrão C) na seção "4.2 DIAGNÓSTICOS", foi dito
Se observar o significado das
_DEBUG
macros 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.fonte
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
_DEBUG
seria 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.
fonte
#if !defined(NDEBUG)
<- @HostileFork não é isso que você quis dizer?#if
nã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
NDEBUG
controla se asassert()
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
NDEBUG
controlar 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.
fonte
#if
código controlado na outra.assert(huge_object.IsValid());
pode ser lento enquantoassert(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.Seja consistente e não importa qual deles. Além disso, se por algum motivo você precisar interoperar com outro programa ou ferramenta usando um determinado identificador DEBUG, é fácil fazer isso.
fonte
Infelizmente
DEBUG
está sobrecarregado. Por exemplo, é recomendável sempre gerar e salvar um arquivo pdb para compilações RELEASE. O que significa uma das opções de-Zx
sinalizador e-DEBUG
vinculador. Embora_DEBUG
esteja relacionado a versões especiais de depuração da biblioteca de tempo de execução, como chamadas paramalloc
efree
. Em seguidaNDEBUG
, desabilitará as asserções.fonte