オブジェクトファイルの書き出し方
たまにはエンジニアらしく(笑)。
つい先日のこと、仕事でプログラムを書いていたときのこと。新人の後輩がmakeをかけていたところ、
「○○さん、コンパイルが通らないんですが」
とヘルプコール。見てみると、コンパイルエラーではなく、リンクエラー。内容としては、関数が多重定義されているというもの。ただ、エラーの出方がちょっと変わっていた。重複定義している関数の箇所が2つ出力されているのだが、2つとも指しているのは同じ場所(つまり、同じソースファイルの定義箇所)。重複しているのは間違いないようだが、何故重複箇所が同一?という珍奇な現象。
grepで関数を探ってみるも、確かに1箇所だけ。それでも、リンカでは重複していると見えているという状態なので、Makefileを見てみた。
よ~く見てみると、一つのソースファイルが重複して宣言される箇所があった。このMakefileはコマンドラインでオプションを指定して作り分けることができるようになっているのだが、その時指定したオプションの指定で重複した分が両方とも適用されるようになっていた。つまり、該当のソースファイルに対して、2回コンパイルが走ることになるわけである。「もしかしてこれか?」と重複しているうちの一方を削除して、再度makeしてみると、リンクエラーは解消した。
まあ、今回のように、ソースファイルを重複して指定するような書き方はまずしないので、こんなことは初めての経験だったが、おかげでコンパイラの挙動を知ることができた。
コンパイラ言語の場合、ソースファイルからオブジェクトファイルを生成(コンパイル)し、オブジェクトファイルやライブラリを結合(リンク)してプログラムファイルを生成する。私は今回のように一つのソースファイルがMakefile内で重複して指定された場合、オブジェクトファイルは上書かれるのだろうと思ったのだが、実際は追記されて書き出されるようである。
#だから、結果として、同一関数が多重定義
#されているというエラーが発生したわけだ。
しかも、同じソースファイルから生成しているから、アドレスまでまるっきり同じになるんですね。
#だから、珍奇な現象と…。
まあ、このMakefile自体はテスト環境構築用のものなので、実際の生成物には影響はないんですけどね。何でこんな書かれ方がされていたのかが謎。
| 固定リンク | 0
「パソコン・インターネット」カテゴリの記事
- IFTTT、無料ユーザーへのTwitter連携機能の提供を終了へ(2023.05.19)
- Google、2年以上利用が無いアカウントを削除へ(2023.05.17)
- LINE、「LINE Out」を5/31にサービス終了(2023.03.22)
- LINE BLOG、6月にサービス終了(2023.01.30)
- 動画配信サービス「GYAO!」、3月にサービス終了(2023.01.16)
コメント