2012-01-12 19 views
1

効率的なC++(古いバージョン)を読んでいて、疑問があります。ここで は、例えば、それは言う:マクロはどのようにプリプロセッサで処理されますか?

あなたはこの

#define ASPECT_RATIO 1.653 

ASPECT_RATIOは、コンパイラによって見られれない場合がありシンボリック名のような何かをするときは、ソースコードがコンパイルされる前に、プリプロセッサによって削除される可能性があります。結果として、ASPECT_RATIOは決してSYMBOLIC_TABLEに入力されないことがあります。それあなたが定数を含むコンパイル時にエラーが出る場合、私はこのparagraph.Howを理解していない

エラーメッセージが1.653を参照していない可能性があるためASPECT_RATIO

、混乱することが何でも同じように、プリプロセッサを削除することができますそれ。どのような理由があり、現実世界でどのように実行可能であるか。

おかげ

+0

これは、[前処理後にファイルを出力する](http://stackoverflow.com/questions/277258/c-c-source-file-after-preprocessing)によってどのような変換が行われているかを見ることができます。 –

答えて

3

を取得します 何がちょうどそのよう、プリプロセッサを削除することができます。どのような の可能性があり、それらが現実世界でどのように実行可能であるか。

基本的には、CとC++のプリプロセッサがどのように動作しているかです。これは、同じ値を何度も何度も繰り返す代わりに、マクロ/定数(#defineディレクティブを使用して作成されたマクロ/定数)を実際の値に置き換えるためです。 C++では、Cスタイルのマクロを使用すると悪いスタイルとみなされますが、C互換性がサポートされています。

名前からわかるように、プリプロセッサは実際のコンパイルよりも前に実行され、基本的にプリプロセッサディレクティブ(#で始まる)の指示に従ってソースコードを変更しています。これには、マクロを値に置き換えたり、#includeの指示に従ったヘッダーファイルを含めるなども含まれます。

これは、コードの繰り返し、マジックナンバー、インターフェイスを共有するのを避けるために使用されます)と他の多くの便利なもの。

+0

申し訳ありませんが、私の質問には全く答えません。私はマクロがどのくらい強くどのように働くのか理解していません。「定義されたマクロはプリプロセッサによってどうやって削除できますか?その理由は? –

+0

@Leoheart私はあなたが尋ねたことに正確に答えました。定義済みのマクロをプリプロセッサでどのように削除できますか?マクロの値で置き換えます。私はちょうどそれ以上のことを書いていましたが、基本的に - それがどういうわけかです。私は続けて、なぜそれが行われたのか説明しました。何が分かりませんか?私は明確にします。 – littleadv

+1

@Leoheart:プリプロセッサは、基本的にコンパイラの前に実行される自動検索置換ツールです。プリプロセッサが '#define ASPECT_RATIO 1.653'を見ると、今度は' ASPECT_RATIO'のすべてのインスタンスを '1.653'で置き換えます。プリプロセッサは、ソースコードテキストから 'ASPECT_RATIO'を削除してから、コンパイラには見えません。 –

1

プリプロセッサは、このように、コンパイラがトークンASPECT_RATIOを見ることはありません...実際のトークン1.653とコードで表示されたトークンASPECT_RATIOのすべてのインスタンスを置き換えます。コードをコンパイルするまでには、プリプロセッサによって置換されたリテラルトークン1.653のみが表示されます。

基本的に、このアプローチで遭遇する「問題」は、ASPECT_RATIOがコンパイラによってシンボルとして認識されないため、デバッガなどでASPECT_RATIOの値を問い合わせることはできません変数。 static const intのようなメモリアドレスを持つ値ではありません(最適化コンパイラはプリプロセッサのように動作し、メモリを格納するための明示的なメモリアドレスの必要性を最適化するため、定数値ではなく、単にコードに現れるリテラル値を代入するだけです)。より大きい関数マクロでは、実際のC/C++関数のような命令アドレスも持たないため、関数マクロ内でブレークポイントを設定することはできません。しかし、より一般的な意味では、マクロをデバッグシンボルとして使用したり、マクロ内でデバッグブレークポイントを設定したりしない限り、この問題を「問題」と呼ぶことはできません。さもなければ、マクロはその仕事をしています。

+0

大丈夫です。しかし、どうしたのですか?それは、私が1.653必要だった目的を正しく解決しましたか? –

+0

はい、それはその目的を解決しました。基本的には、「ASPECT_RATIO」はコンパイラによってシンボルとして認識されないため、デバッガなどでは、変数の場合にはASPECT_RATIOという値を問い合わせることはできません。 'static const int'のようなメモリアドレスを持つ値ではありません(最適化コンパイラがプリプロセッサのように動作し、明示的なメモリの必要性を最適化するために" may "と言います)アドレスに定数値を格納する代わりに、コード内のどこにでもリテラル値を代入するだけです)。しかし、私はこれを「問題」と呼ぶのかどうかはわかりません。 – Jason

+0

私はあなたのポイントを正確にJasonにしました。ありがとう。私はちょうど私の質問を編集し、質問の部分は今あなたから答えられている。ありがとう。 –

3

これは単にグローバル検索だと、マクロはとても危険である理由ですコンパイラ

に渡す前に、ファイルに「1.653」と「ASPECT_RATIO」と交換してください。あなたは#define max 123、変数int max = 100を持っている場合、コンパイラはint 123 = 100を取得すると、あなたは、私が逆quotes.Howの下にこの段落を理解していない紛らわしいエラーメッセージ

+0

I午前混乱 の#include の#define最大123 INTのmain(){int型 max123 = 10。 std :: cout << max123 << std :: endl; } 私はこれを試してみました。これはコンパイラに依存するかもしれません..? –

+0

これは間違っています。Cプリプロセッサは、任意の文字列一致でトークンで動作します。 – Alex

+0

@Leoheartいいえ、その間違った例です。プリプロセッサは部分文字列ではなくトークンを扱います。あなたのコードで、iostreamをインクルードした後に 'int max'を定義すると、何らかのコンパイルエラー(コンパイラ間でのエラーの種類)が発生する可能性があります。 – littleadv

関連する問題