Quanto a muitas perguntas, a resposta desta pergunta é que depende . Em vez de dizer o que é melhor , dei exemplos e objetivos em que um é melhor que outro.
Tanto o pré-processador quanto a constante têm seus próprios locais de uso apropriado.
No caso do pré-processador, o código é removido antes do tempo de compilação. Portanto, é mais adequado para situações em que o código não deve ser compilado . Isso pode afetar a estrutura do módulo, as dependências e pode permitir a seleção dos melhores segmentos de código para os aspectos de desempenho. Nos seguintes casos, é necessário dividir o código usando apenas o pré-processador.
Código de várias plataformas:
por exemplo, quando o código é compilado em plataformas diferentes, quando o código depende de números de versão específicos do SO (ou mesmo da versão do compilador - embora isso seja muito raro). Por exemplo, quando você está lidando com códigos de código de pequeno e grande endien - eles devem ser segregados com pré-processadores em vez de constantes. Ou, se você estiver compilando código para o Windows, Linux e certas chamadas do sistema são muito diferentes.
Patches experimentais:
Outro caso em que isso é justificado é algum código experimental que é arriscado ou alguns módulos importantes que precisam ser omitidos que terão uma ligação ou diferença de desempenho significativa. A razão pela qual alguém desejaria desativar o código via pré-processador, em vez de se esconder em if (), é porque podemos não ter certeza dos bugs introduzidos por esse conjunto de alterações específico e estamos executando com base experimental. Se falhar, não devemos fazer nada além de desabilitar esse código na produção do que reescrever. Algum tempo é ideal #if 0
para comentar o código inteiro.
Lidando com dependências:
Outro motivo em que você pode gerar Por exemplo, se você não deseja suportar imagens JPEG, pode ajudar a se livrar da compilação desse módulo / stub e, eventualmente, a biblioteca não vinculará (estaticamente ou dinamicamente) a isso módulo. Às vezes, os pacotes são executados ./configure
para identificar a disponibilidade dessa dependência e se as bibliotecas não estiverem presentes (ou o usuário não quiser habilitar), essa funcionalidade será desabilitada automaticamente sem vincular-se a essa biblioteca. Aqui é sempre benéfico se essas diretivas forem geradas automaticamente.
Licenciamento:
Um exemplo muito interessante de diretiva de pré-processador é o ffmpeg . Possui codecs que podem potencialmente infringir patentes por seu uso. Se você baixar o código-fonte e compilar para instalar, ele pergunta se você deseja ou mantém essas coisas afastadas. Manter códigos ocultos sob algumas condições, se as condições ainda puderem levar você a tribunal!
Código copiar e colar:
Macros Aka. Este não é um conselho para o uso excessivo de macros - apenas que as macros têm uma maneira muito mais poderosa de aplicar o equivalente ao passado da cópia . Mas use-o com muito cuidado; e use-o se você souber o que está fazendo. Constantes, é claro, não podem fazer isso. Mas pode-se usar inline
funções também se isso for fácil de fazer.
Então, quando você usa constantes?
Quase em qualquer outro lugar.
Fluxo de código mais organizado:
em geral, quando você usa constantes, é quase indistinguível das variáveis regulares e, portanto, é um código legível melhor. Se você escrever uma rotina de 75 linhas - tenha 3 ou 4 linhas após cada 10 linhas com #ifdef MUITO incapaz de ler . Provavelmente, dada uma constante primária governada pelo #ifdef e use-a em um fluxo natural em todos os lugares.
Código bem recuado: Todas as diretivas de pré-processador, nunca funcionam bem com código recuado . Mesmo se o seu compilador permitir a indentação de #def, o pré-processador C do Pré-ANSI C não permitiu espaço entre o início de uma linha e o caractere "#"; o "#" principal sempre deveria ser colocado na primeira coluna.
Configuração:
Outra razão pela qual constantes / ou variáveis fazem sentido é que elas podem evoluir facilmente de serem vinculadas a globais ou no futuro podem ser estendidas para serem derivadas de arquivos de configuração.
Uma última coisa:
nunca USE diretivas de pré-processador #ifdef
para #endif
cruzar o escopo ou { ... }
. ou seja, início #ifdef
ou fim de #endif
em lados diferentes de { ... }
. Isso é extremamente ruim; pode ser confuso, pode ser perigoso em algum momento.
Obviamente, isso não é uma lista exaustiva, mas mostra uma grande diferença, onde o método é mais adequado para uso. Não se trata realmente de qual é o melhor , é sempre mais do que um que é mais natural usar em determinado contexto.