多くの質問については、この質問の答えはそれが依存するということです。どちらが良いかを言う代わりに、私はどちらかが他より優れている例と目標を与えました。
プリプロセッサと定数の両方には、適切な使用法の独自の場所があります。
プリプロセッサの場合、コードはコンパイル前に削除されます。したがって、コードがコンパイルされないことが予想される状況に最適です。これは、モジュールの構造、依存関係に影響を与える可能性があり、パフォーマンスの観点から最適なコードセグメントを選択できる場合があります。以下の場合、プリプロセッサのみを使用してコードを分割する必要があります。
マルチプラットフォームコード:
たとえば、コードが異なるプラットフォームでコンパイルされた場合、コードがOSの特定のバージョン番号(またはコンパイラのバージョン)に依存している場合(これは非常にまれです)。たとえば、リトルエンディアンとビッグエンディアンの対応するコードを扱う場合、定数ではなくプリプロセッサを使用して分離する必要があります。または、WindowsとLinuxのコードをコンパイルしていて、特定のシステムコールが大きく異なる場合。
実験的なパッチ:
これが正当化するもう1つのケースは、リスクのある実験的なコード、または大幅なリンクまたはパフォーマンスの違いがある省略する必要がある特定の主要なモジュールです。if()の下に隠すのではなく、プリプロセッサを介してコードを無効にしたい理由は、この特定の変更セットによって導入されたバグを確信できない可能性があり、実験的に実行しているためです。失敗した場合は、本番環境でそのコードを無効にする以外に何もする必要はありません。コード全体をコメント化するのに使用するのが理想的な場合もあります。#if 0
依存関係の処理:
生成する可能性のあるもう1つの理由たとえば、JPEG画像をサポートしたくない場合は、そのモジュール/スタブのコンパイルをやめると、最終的にライブラリが(静的または動的に)リンクしなくなります。モジュール。./configure
そのような依存関係の可用性を特定するためにパッケージが実行される場合があり、ライブラリが存在しない場合(またはユーザーが有効にしたくない場合)、そのライブラリとリンクしないと、そのような機能は自動的に無効になります。ここで、これらのディレクティブが自動生成される場合は常に有益です。
ライセンス:
プリプロセッサディレクティブの例で非常に興味深いのはffmpegです。それはその使用によって特許を侵害する可能性のあるコーデックを持っています。ソースをダウンロードしてコンパイルしてインストールする場合、そのようなものを使用するかどうかを尋ねられます。条件がまだあなたを法廷に着地させることができるならば、いくつかの下でコードを隠しておく!
コードのコピーと貼り付け:
別名マクロ。これは、マクロを使いすぎることへのアドバイスではありません。マクロには、コピーペーストを同等に適用するためのより強力な方法があります。ただし、慎重に使用してください。そして、あなたがあなたが何をしているか知っているなら、それを使ってください。もちろん定数はこれを行うことができません。しかしinline
、それが簡単であれば、関数を使用することもできます。
では、いつ定数を使用しますか?
ほとんどどこでも。
より適切なコードフロー:一般に、定数を使用する場合、定数は通常の変数とほとんど区別がつかないため、コードが読みやすくなります。75行のルーチンを作成する場合は、#ifdefを使用して10行ごとに3行または4行を置いてください。おそらく#ifdefによって管理される一次定数が与えられ、どこでも自然な流れの中でそれを使用します。
適切にインデントされたコード:すべてのプリプロセッサディレクティブは、適切にインデントされたコードではうまく機能しません。場合でも、あなたのコンパイラが#defのインデントを許可しない、プリANSI Cプリプロセッサは、ラインの開始と「#」の文字の間にスペースを許可しませんでした。先頭の「#」は常に最初の列に配置する必要がありました。
構成:
定数/または変数が理にかなっているもう1つの理由は、定数または変数がグローバルにリンクされていることから簡単に進化できること、または将来的に構成ファイルから派生するように拡張できることです。
最後に
、スコープをまたぐためにプリプロセッサディレクティブを
使用しないでください。つまり、の異なる側の開始または終了。これは非常に悪いです。混乱を招く可能性があり、危険な場合もあります。#ifdef
#endif
{ ... }
#ifdef
#endif
{ ... }
もちろん、これは完全なリストではありませんが、どの方法がより使いやすいかという明確な違いを示しています。どちらが優れているかということではなく、特定のコンテキストでどちらがより自然に使用できるかは常により重要です。