2016-04-06 12 views
0

私はかなり新しいC + +であり、次の割り当てが与えられています:特定のファイルに依存関係のバグがあるかどうかを確認するにはどうすればよいですか?

私は次のファイルのセットを持っていると仮定します:alpha.cpp、bravo.cpp、charlie.cpp、私はそれらのファイルに依存性のバグがあるかどうかをチェックするプログラム。

私は、プログラムがファイルを読み込ませ、隣接リストグラフを作成し、頂点として各ファイルを持ち、一方のノードから別の.cppファイルに別の.cppファイルが含まれていれば、有向エッジを指し示すようにします。だから、全体的に、私は、グラフにバックエッジがあるかどうかを確認するために、グラフの深さの最初の検索を実行する必要があります。

これは正しいトラックでしょうか?私は何をすべきか理解しているように感じますが、正確に実装する方法がわかりません。

+1

依存関係のバグとは何ですか? – immibis

+0

@immibisファイル間に循環的な依存関係があるときです。ですから、alpha.cppはcharlie.cppを使い、charlie.cppはalpha、cppを使います。 – trungnt

+0

[DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph)と[Check for Cycles](http:// www。com)を作成します。 geeksforgeeks.org/detect-cycle-in-a-graph/)。 –

答えて

3

パージングマジックを少し使ってビルドシステムを使用したいと思います。私はたくさんのプロジェクトに使用するMakefileを持っていますhere。インクルードを解析し、インクルードのターゲットを生成します。

メイクのようなツールについては、グラフを横断する必要があります。彼らはあなたの部分的な順序(依存関係の宣言)をすべて取って、完全な順序を得るためにそれをトポロジカルな並べ替えを行います(AがBに依存し、BがAの前にあるようにファイルの線形化)。

しかし、トポロジカルな並べ替えに関することは、直接アサイクルグラフの場合のみ存在するということです。したがって、Makefileのような依存関係を生成してサイクルがある場合、ビルドは失敗します。これは、再帰的に物事を組み込もうとしたときに起こるためです。

+0

私はコメントのElliot Frischの提案によるDAGの作成について考えています。私が抱えている問題は、alpha.cppがbravo.cppに依存していることを見つけるために、どのファイルをC++に読み込ませるのですか? #include 'bravo.cpp'を探してもらえますか? – trungnt

+0

したがって、一般的に.cppファイルは実際には互いに依存しません。通常はヘッダーです。 C++でやりたければ、あなたが言ったようにファイルを解析し、#include文を探す必要があります。私は正規表現ライブラリ(おそらくPCRE)を使用してそれらを取得したいと思います。グラフを隣接関係リストとして構築し、それをトポロジ的に並べ替えることができます。あなたは私がそれにリンクしているMakefileから正規表現を盗むことを歓迎します。 –

+0

ヒントや提案をありがとう。これはとても役に立ちました!私は実際に私のインストラクターが私たちにタスクを手助けするためにmakefileを使用してもらいたいのかどうかはわかりません。私はこれがすべて私のmain.cppで行われなければならないと思う。基本的に私はファイルを入力する必要があり、出力には "charlie - > bravo - > alphaの順にファイルをコンパイルできます。" – trungnt

0

あなたが依存関係を確認するためのツールを探しているなら、私が使用して検討したい:

  • makedependまたはg++ -MD(またはclang++ -MDを)#include -dependenciesを生成します。次に、ループを検出するためのグラフを作成します。
  • およびnm-Uおよび--defined-only)を使用して、オブジェクトファイルで定義され、必要なシンボルを読み取ることができます。定義され、宣言されたシンボル(/usr/lib64/libstdc++.so.6のように定義されたシンボルを含む)のリストを比較するだけで、シンボルがまったくないかどうかを調べることもできます。
1

脇に:あなたの質問のコメントごとの「依存性バグ」の定義はそれほど役に立ちません。一般に、a.hb.ha.hなど)は、どのような種類のバグである必要はありません。それらを含むファイルがコンパイルされている場合、明らかに有効なC++を持っています。だから、バグではありません。次のシナリオが発生:

  1. 特定の依存サイクルは不要かもしれません:いくつかのb.hは本当にa.hを含める必要はないかもしれません。コンパイルは成功します。

  2. 特定の依存サイクルが必要になることがありますが、有効な:一部b.ha.hからコンテンツを必要とするかもしれません、そして、それはa.hに戻って何かを提供するかもしれないが、それが動作するように順序付けされている文と依存関係があります。コンパイルは成功します。

  3. 指定された依存関係のサイクルが必要であり、無効である可能性があります。前述のように依存関係を満たすことは不可能です。コンパイルが失敗します。

#3を検出するには、ファイルをコンパイルするだけで済みます。コンパイルが失敗した場合は、依存関係のバグがある可能性があります。

a.hb.hの宣言と定義の並べ替えが可能であり、#3から#2を変換するインクルードステートメントの可能性があります。

#2と#1は必ずしもバグではありませんが、ファイルが完全に解析されていることを確認する必要があります。

もちろん、は、プロジェクトで許可されていないと宣言することができます。だから彼らはあなたのプロジェクトルールに違反しているかもしれません。おそらくあなたはそれらをバグと呼ぶことができます:)

関連する問題