0

私たちのチームと一緒に、オンライン イベント用に C 言語を使用してデッドコード除去アルゴリズムを作成しようとしています。

要件は.....

  1. C プログラムのソース ファイルを読み取るには、多くの形式のデッド コードが含まれています。
  2. そして、出力はすべてのデッドコードのないファイルである必要があります。

インターネットをサーフィンしているときに、SOリンクに出くわしました...

コード内のどの部分がまったく使用されていないかを知るにはどうすればよいですか?

レガシ C/C++ プロジェクトでのデッド コード検出

これらのリンクを見る前に、基本的なアイデアがありました... 通常のファイル ストリームを使用して入力 C ファイルを 1 行ずつ読み取り、文字列配列に格納します。次に、これらの文字列を分析し、if(0) や if(1) などの非常に基本的なデッド コードを特定します。そして、括弧を維持するためのスタックを作成します。そしてもっと...

しかし、これには大きな問題があります。このアイデアは、デッドコードを削除するよりも、文字列操作でより多くのことを行うことにつながります。

しかし、これらのリンクを見た後... Clang ライブラリ、抽象構文ツリー、Control-Flow-Graph などについて知るようになりました...

しかし、私たちはそれらのライブラリとそれらの概念について非常に初心者です。それらが C コードの解析に使用されていることがわかりました。

したがって、これらのAST、CFGに関するいくつかの基本的なアイデアと、コードでそれをどのように使用できるかを説明する基本的なガイダンスが必要です...

そのclangライブラリをmath.hのような通常のライブラリとして含めることはできますか?

そのライブラリはどこからダウンロードできますか?

これらの Clang ライブラリを Windows で使用できますか?

4

2 に答える 2

4

制御フロー グラフの概念については説明できますが、ライブラリ自体には詳しくありません。

コンセプトはシンプルです。グラフの 1 つのノードとして、一連のコード行 (つまりif、 、gotoまたは関数呼び出しまたはラベルがないもの) を想像してください。すべてgotoの または 関数呼び出しは、現在のノードから、gotoラベルがあるノードまたは呼び出している関数への方向リンクを作成します。関数自体は単純なノードではなくグラフである可能性があることに注意してください。これは、if内部に s または他の関数呼び出しが含まれている可能性があるためです。各関数呼び出しは、関数のリーフ ノード (関数がある場所return) から、関数呼び出しの直後のコードを含むノードへの方向リンクも作成します。(関数はコードの多くの部分で呼び出すことができるため、関数グラフから発信される多くのリンクを作成できます)

同様に、 がある場合if、現在のノードからステートメントifの部分とelse部分の両方への 2 つの方向リンクがあります (適切な場所へのリンクが 1 つしかないことを検出したり、あなたが言ったようにしない限り)ifif(0)if(1)

グラフのルートは のエントリ ポイントですmain。デッドコードを見つけるためにしなければならないことは、グラフをルート位置から (たとえば DFS または BFS を使用して) 単純にトラバースし、最後にアクセスされなかったノードを確認することです。これは、プログラムがどの方向に進んでも、それらの場所に到達しないコード内の場所であるデッド コードを示します。

これを自分で実装したい場合は、再帰的なアプローチを取ることができます (コードの解析に似ていますが、より単純です)。たとえば、次のifように言う場合:

typedef char *line;
FlowGraph *get_flow_graph(line *code)
{
    FlowGraph *current_node = malloc(sizeof *current_node);
    current_node->flow_to = malloc(some_maximum * sizeof *current_node->flow_to);
    current_node->flow_to_count = 0;
    ...
    if (is_if_statement(code[0]))
    {
        FlowGraph *if_part = get_flow_graph(code + 1);
        FlowGraph *else_part = get_flow_graph(code + find_matching_else(code));
        current_node->flow_to[current_node->flow_to_count++] = if_part;
        current_node->flow_to[current_node->flow_to_count++] = else_part;
    }
    else
    ...
}
于 2011-08-26T15:08:23.153 に答える
0

DMS Software Reengineering Toolkitによって抽出された制御グラフとデータ フローグラフの例を確認できます。

DMS のデータ フロー分析機構とそのC フロント エンドを使用して、非常に大規模なアプリケーション (2600 万行の C)でこれを行いました。 C系。

于 2011-08-26T16:51:16.763 に答える