32

マクロを定義する場所はたくさんあります。マクロを自分のプロジェクトで定義すると、それらの定義位置を簡単に見つけることができます。しかし、有名なオープンソース プロジェクトについて学ぼうとすると、よく次のような質問に悩まされます。マクロのソースはどこにあるのか、その定義を取得できない場合、それらのいくつかは理解できません (たとえば、それらのいくつか)。名前から推測できます)。たとえば、apache からのいくつかのステートメント:

#if defined(__osf__) && defined(__alpha),

#elif defined(__NSIG)

私の知る限りでは、マクロの元になる可能性のある場所がいくつかあることを知っています。

  1. このプロジェクト自体から、いくつかのソースファイルで(これは、いくつかのツールで見つけることができるため、最も簡単です)
  2. 3番目のライブラリのヘッダーファイルから、grepできます
  3. c/c++ 標準ヘッダー ファイルから (Linux のどこにありますか?)
  4. OSから(Linuxのどこにありますか?)
  5. 構成ツールによって自動的に生成されます(苦い、わかりません)
  6. gcc/g++ のようなコンパイラ ツールから、またはメイクファイルでマクロを定義できます。

相談したい質問があります:

  1. OS で定義されたものと gcc/g++ で定義されたものを区別し、ツールによって生成されたマクロを構成するにはどうすればよいですか?それぞれに特徴がありますか?
  2. OSまたは標準Cまたはコンパイラによって定義されたもののソースを見つける方法は? 例:grepまたはfindユーティリティの使用
  3. __strange___マシン全体をくまなく調べても のような 1 つのマクロが見つからない ( )とはどういう意味cd /;grep __strange___ -rですか?

それらを区別し、それらのソースを見つけるための原理と方法を教えてくれてありがとう!

4

8 に答える 8

15
  1. OS で定義されたものと gcc/g++ で定義されたものを区別し、ツールによって生成されたマクロを構成するにはどうすればよいですか?それぞれに特徴がありますか?

大部分は、どこかのヘッダー ファイルで定義されています。gcc -dN -Eここで役立ちます。警告: このアプローチを使用する場合は、ソースをオブジェクト ファイルにコンパイルするときとgcc -dN -E同じインクルード パス、同じ-D<name>コマンド ライン オプション、同じ環境変数 (... など)を使用して呼び出す必要があります。CPATH

  1. OSまたは標準Cまたはコンパイラによって定義されたもののソースを見つける方法は? たとえば、grep または find ユーティリティを使用する

RTFM。細かいマニュアルを読んでください。

  1. __strange__マシン全体をくまなく調べても のような 1 つのマクロが見つからない場合は、どういう意味(cd /;grep __strange___ -r)ですか?

そのシンボルがコンピューターで定義されていないことを意味している可能性があります。問題のコードが、C++ 標準に完全に準拠していないさまざまなシステムやさまざまなコンパイラをターゲットとするオープン ソース パッケージからのものであるとします。典型的なアプローチは#ifdef __some_bizarre_os__、コードの重要な部分で使用することです。そのシンボルは、Bizarre OS を実行しているマシンでのみ定義されます。あなたのマシンでは定義されません。

残念ながら、それだけではありません。grep がどこにも見つからなくても、シンボルは定義されている可能性があります。makefile は 2 つの文字列を連結-D__strange__、コンパイラへの単一のコマンド ライン引数を形成することができます。このオプション-D__strange__は、makefile で使用される環境変数の 1 つに隠れている可能性があります。一部のプロジェクトで義務付けられている ~/.tcshrc ファイルは、非常に複雑になる可能性があります。

Update
gcc -dM -Eはマクロの定義を表示しますが、マクロが定義された場所は表示しません。はるかに優れたオプションは、使用gcc -dN -Eしてから、頭文字で始まらない行を除外することです#

于 2012-06-29T11:02:25.910 に答える
5

gccコンパイラで定義されたマクロは次のように表示できます

gcc  -dM -E a.c

それ以外は、すべて含まれているファイルとソースから取得されます。

マクロが見つからない場合は、条件がfalseと評価されることを意味します。

-vオプションを使用することもできます。これにより、デフォルトのインクルードディレクトリがどこにあるかがわかります。

マクロがどのファイルからのものであるかを確認するには、次のようにします。

gcc -E $your_compile_options $your_c_file | \
egrep "^# " | grep -v '<'| cut -f 2 -d '"' | \
sort | uniq |
while read line
    do
            grep -l $your_macro $line
    done
于 2012-06-29T07:18:27.923 に答える
3

他の人が言ったように、オプションのgcc1つを使用して、マクロが定義されている場所を見つける必要があります。これらのオプションは によって出力されないため、マニュアルの3.11章の検索を使用して読む必要があります。-dgcc -v --help-dCHARS

最後に私の手順は次のとおりです。

  1. 使用するgcc ... -E -dD
  2. 出力ファイルで定義を見つける
  3. #(ハッシュとスペース) を逆方向に検索して、ファイルを表示します。
于 2014-05-09T07:53:58.567 に答える
2

オープンソース プロジェクトを研究している場合は、それをビルドできるようにセットアップしていると思います。探しているマクロを含むファイルを 1 つ選択し、コンパイラを使用して前処理されたファイルを生成します。実際のオプションは、使用しているコンパイラによって異なります。gcc の場合は -E です。詳細については、こちらを参照してください。

プロジェクトのビルド システムを使用してファイルを実際にコンパイルし、プリプロセッサの実行を成功させるために必要なオプションを確認する必要があることに注意してください。

前処理されたファイルを取得したら、マクロを検索するだけです。インクルードされた各ファイルのパス名を生成するプリプロセッサ オプションがあります。

更新: マクロはプロセッサによって展開されるため、このアプローチは明らかに機能しません。したがって、その拡張された形やその効果を認識できなければ、ほとんど役に立ちません。

もう少し便利なのは、インクルードされたファイルの正確なシーケンスをコンパイラに出力させることです。これは、-H オプションを使用して gcc で実現されます。

于 2012-06-29T07:30:44.613 に答える
2

これらのマクロはコンパイル定数のようです。

このようなマクロを使用して、コードのこの部分をコンパイルする必要があり、コードのこの部分をコンパイルしないことをコンパイラーに伝えることをお勧めします。

プロジェクト ワークスペースでそれらを検索できない場合は、プログラム フローを調べて、アプリケーションに必要なコードの部分を決定し、それぞれのマクロを定義する必要があります。

例えば;

#ifdef (_CASE1_)

...
...
...

#elif (_CASE2_)

...
...
...

#endif

上記の例で、下に記載されているコードが_CASE1_アプリケーションで必要な場合は、 を定義する必要があります_CASE1_。例えば#define _CASE1_

それが役に立てば幸い...

于 2012-06-29T07:45:52.500 に答える
0

Eclipse などの IDE を使用する必要があります。マクロを右クリックして [宣言を開く] をクリックすると、マクロが定義されているファイルと行が表示されます。

一部のマクロは、gnu コンパイラにフラグとして渡されるため、ヘッダー ファイルで定義されていない場合もあります (例: -DMYMACRO)。

于 2012-06-29T07:29:55.190 に答える