• ベストアンサー

LNK2005

Visual C++ Version5.0を使っています。 OSはWindows XPです。 translator.cpp parser.cpp scanner.h という三つのファイルをビルドしようとすると translator.obj : error LNK2005: "int error_flag" (?error_flag@@3HA) は すでに parser.obj で定義されています というエラーがそれぞれの変数ごとに20個出て、最後に ebug/COSC47101.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました link.exe の実行エラー と表示されます。それらの変数はすべて"scanner.h"で定義されており、 二つの.cppファイルがincludeしているのが原因だということは分かっています。 しかし、どうやって解決すればよいのでしょうか? 過去ログを参考にして二つの.cppファイルの中で #if !defined(HOGE_X) #define HOGE_X #endif //include files #include "scanner.h" とやっても全然駄目です。 どうか解決するまで手取り足取り教えてください。 お願いします。m(__)m

質問者が選んだベストアンサー

  • ベストアンサー
  • Senna_FF
  • ベストアンサー率45% (153/334)
回答No.5

もう少しがんばりましょうか。 1.次はコンパイルエラーが出たようですが、これはエラーの内容そのままです。  「token」なる変数の型はなんですか?と聞いています。  型をユーザ定義の、クラスや構造体等にしていませんか?  また、その型定義を「scanner.h」でしていませんか。  当初は、リンケージエラーでお困りのようでしたから、「scanner.h」参照時は、  コンパイルは通っていたことになります。  まずは、そこまで戻りましょう。 2.次にANo.3のqwertyfさんがおっしゃるように、ソースに手を加えてください。  (1)「scanner.h」の「error_flag」変数を、extern宣言する。      → extern int error_flag;  (2)「translator.cpp」、「parser.cpp 」では、そのまま「scanner.h」をインクルードする。  (3)「translator.cpp」もしくは「parser.cpp 」のどちらかに、「error_flag」の実態を宣言します。      → int error_flag;   3.コレで駄目なら、もう一手。qwertyfさんがおっしゃるとおり、ソース公開してみては。   少なくとも「scanner.h」の、変数宣言部は欲しいですね。 ちなみに、"LNK2005"でサイト検索すると、うれしいことが起こるかもです。 (結構くわしく解説してるかたが・・・)

sucker
質問者

お礼

#4さんのお礼に書きましたとおり、自分の勘違いが原因でした。 深く反省するとともに今後は同じ過ちを繰り返さないように努めたいと思います。 ありがとうございました!

その他の回答 (4)

  • qwertyf
  • ベストアンサー率51% (14/27)
回答No.4

#3です。 エラーを見るとやはりなんか別の原因っぽいですね… C2501: 'token' : 識別名を宣言するのに、型が指定されていません。 というのは型名が宣言されていないのにその型を使ってしまっている 時によく出るエラーです。 構文エラーは文法が間違っていたりすると出ます。 出来ればエラー周辺のソースを出してくれると有り難いのですが…

sucker
質問者

お礼

大変、申し訳ないです。m(__)m 結論から申しますと、translator.cppとparser.cppは別々にビルドされるべきだったようです。 もともとこれらのファイルは二年前のプロジェクトで作ったもので そのときにうまく動いていたことは覚えていたのですが 別々にビルドしていたことはすっかり忘れていました。 何が原因なんだろう?とまじまじと見てみると translator.cppにもparser.cppにもmain()があることに気付きました。 ←もっと早く気付け よって →parser.cppをクリック →設定… →一般タブ →「このファイルをビルドしない」にチェック →OK で解決です。本当に一緒にビルドするのであればヘッダーの名前を変えて変数名も 変えてやる必要があるでしょうね。幸運にもtranslator.cppとparser.cppとの間に データのやり取りはありません。(ですから別々でよい訳ですが) 自分の勘違いのせいで面倒を掛けてすみませんでした。 ポイントを差し上げ次第速やかに逝ってきます。 ありがとうございました!

  • qwertyf
  • ベストアンサー率51% (14/27)
回答No.3

1.どこかしらの cpp ファイルに変数の「実体」を定義します。 translator.cpp, parser.cpp, あるいは新しく作った cpp ファイルの中で、 int a, b; のように変数を定義します。 2.どこかしらのヘッダーファイルで変数を外部参照することを宣言します。 この場合 scanner.h ですね。また新たにヘッダーを作っても構いません。 その中で先ほどの定義と同じものを、行の先頭に extern を付けて書きます。 extern int a, b; といった感じ。 3.該当する変数を参照する cpp ファイルに2のヘッダーファイルをインクルードします。 translator.cpp, parser.cpp に #include "scanner.h" のように追加すればOKです。 #if 文などでごちゃごちゃした処理をする必要もないと思います。 これで大丈夫かな・・・?

参考URL:
http://okuyama.mt.tama.hosei.ac.jp/unix/C/slide84-1.html
sucker
質問者

お礼

手順に沿ってやってみましたがうまくビルドできませんでした。 エラーの数やメッセージにはまったく変化がありません。 translator.cppを含めるとうちの教授でも解決できませんでしたから 質問に書いたよりも何かもっと複雑な問題なのかもしれません。 まだ、解決の方法が残されているのであればお聞きしたいのですが ないようであれば締め切ってポイントを差し上げます。 ありがとうございました。

  • Senna_FF
  • ベストアンサー率45% (153/334)
回答No.2

すいません。まったく見当違いな回答してました。 そもそもこのエラー内容は、error_flagという変数の実体があちこちにあるという エラーですよね。(外部変数にしてますよね?) translator.cppではこの変数へのアクセスはあるのですか? ないのならば、ヘッダをインクルードしない。 あるなら、ヘッダはインクルードせず変数をextern宣言してください。

sucker
質問者

お礼

はい、translator.cppでもこの変数へのアクセスはあります。 ヘッダをインクルードせず変数をextern宣言しましたが 今度はscanner.hで他に定義されている変数について怒られ、エラーは70個に増えました。 translator.cpp C:\Program Files\DevStudio\MyProjects\COSC47101\translator.cpp(15) : error C2501: 'token' : 識別名を宣言するのに、型が指定されていません。 C:\Program Files\DevStudio\MyProjects\COSC47101\translator.cpp(15) : error C2239: 無効なトークン 'identifier' が 'token' の宣言の後にあらわれました。 C:\Program Files\DevStudio\MyProjects\COSC47101\translator.cpp(15) : error C2061: 構文エラー : 識別子 'next_token' がシンタックスエラーを起こしました。 ↑こんな感じで70個 実は前回取っていたクラスの教授に見てもらい、今回はtranslator.cppはいらんだろう(recursive descent parserがいるだけ)ということで parser.cppとscanner.hだけでビルドしてうまくビルドできました。 ただ、translator.cppもそのうち使うことになるんで解決しておきたいです。 何か間違っていますでしょうか? まだ他に解決方法はありますか?

sucker
質問者

補足

お礼を書くのを忘れていました。 ありがとうございました。

  • Senna_FF
  • ベストアンサー率45% (153/334)
回答No.1

↓#if のネスト内に#includeを書き込まないと意味ないと思いますが。 #if !defined(HOGE_X) #define HOGE_X //include files #include "scanner.h" #endif

sucker
質問者

お礼

ありがとうございます。 ご指摘通りにしましたが、結果はまったく同じです。 parser.cppは #if !defined(HOGE_X) #define HOGE_X #include "scanner.h" #endif translator.cppの方には標準のヘッダー<string.h>がありますので #include <string.h> #if !defined(HOGE_X) #define HOGE_X #include "scanner.h" #endif としました。何か間違いなどがあればまたご指摘お願いします。m(__)m

関連するQ&A