オブジェクト ファイル (C 言語) の gcc 出力はコンパイルごとに異なりますか? 時間固有の情報はなく、コンパイル オプションやソース コードの変更もありません。リンクされたライブラリ、環境変数にも変更はありません。これは VxWorks MIPS64 クロス コンパイラです。個人的には変えてはいけないと思っています。しかし、ランダムに、生成された命令が変更されることがあります。理由はわかりません。誰でもこれに光を当てることができますか?
5 に答える
g ++でも同様の問題がありました。4.3 より前のバージョンでは、毎回まったく同じオブジェクト ファイルが生成されました。4.3 (およびそれ以降?) では、 -g やその他の記録がなくても、マングルされたシンボル名の一部が実行ごとに異なります。おそらく、タイムスタンプまたは乱数を使用します (そうでないことを願っています)。明らかに、これらのシンボルのいくつかは .o シンボル テーブルに組み込まれ、違いが生じます。オブジェクトファイルを削除すると、それらは再び等しくなります (バイナリ比較に関して)。g++ -c file.C ; ストリップ file.o; cmp file.o origfile.o
これはどのように構築されていますか?たとえば、まったく同じ Linux カーネルをビルドした場合、ビルドごとにインクリメントされるカウンターが含まれています。GCC には、プロファイラー情報を使用してコード生成をガイドするオプションがあります。プロファイリング情報が変更された場合、コードも変更されます。
何を分析しましたか?生成されたアセンブリ、オブジェクト ファイルの objdump、または実行可能ファイルですか? 異なるバージョンをどのように比較しましたか? コンパイラ/アセンブラ/リンカーのタイムスタンプではなく、実行可能コードを見たのですか?
環境に何か変化はありましたか?新しいライブラリ (およびヘッダー ファイル/宣言/マクロ定義!)? 新しいコンパイラ、リンカ? 新しいカーネル (はい、一部のヘッダー ファイルはカーネル ソースに含まれており、同梱されています)?
環境変数の変更 (コンパイルを行っている別のユーザー、別のマシン、ネットへの別の接続により、ビルドに入る別の IP アドレスが得られます)?
ビルド プロセスを詳細にトレースしてみます (ビルドを実行して出力をファイルにキャプチャし、もう一度実行して比較します)。
完全に謎...
なぜそれを変える必要があるのですか?いつも同じ結果です。これを試して:
for i in `seq 1000`; do gcc 1.c; md5sum a.out; done | sort | uniq | wc -l
答えは常に1
です。ニーズに合わせて交換1.c
してください。a.out
上記はgcc
、同じソースを何回コンパイルしたときに、いくつの異なる実行可能ファイルが生成されるかをカウントします1000
。
私の gcc は、まったく同じ入力に対して異なるコードを生成することがあります。出力オブジェクト ファイルの違いは、正確に 1 バイトです。
オブジェクト ファイルの 1 つが無効であるため、リンカ エラーが発生することがあります。通常、別のバージョンを再コンパイルすると、リンカー エラーが修正されます。
Suse Linux Enterprise の gcc バージョンは 4.3.4 です。gcc パラメータは次のとおりです。
cc -std=c++0x -Wall -fno-builtin -march=native -g -I<path1> -I<path2> -I<path3> -o obj/file.o -c file.cpp
同じ効果を感じた人がいたら教えてください。