• ベストアンサー

分割コンパイルの方法がわかりません‥(Studio.NET)

mainとsubという2つのcppファイルと各ヘッダファイルで分割コンパイルを試みましたがうまくいきません・・。 何が間違っているのでしょう・・。 エラーメッセージ error LNK2005: "char * a" (?a@@3PADA)は既にmain.objで定義されています。 fatal error LNK1169: 1つ以上の複数回定義されているシンボルが見つかりました。 と表示されます。ファイルソースは以下です。どなたか教えてください>< ----------(main.h)---------- char a[100]; ----------(main.cpp)---------- #include<stdio.h> #include "main.h" #include "sub.h" int main(){  sprintf(a,"hello.");  sub_write();  return 0; } -----------(sub.h)----------- void sub_write(); -----------(sub.cpp)------------- #include <stdio.h> #include "main.h" #include "sub.h" void sab(){  printf("%s\n",a); } return; }

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

  • ベストアンサー
  • ddnp009
  • ベストアンサー率25% (15/58)
回答No.4

エラーメッセージのとおり。 グローバル変数 char a[100]が重複します。 回避するには、main.hを書き換えましょう。↓ #ifndef hoge_main_h_included_hogehoge #define hoge_main_h_included_hogehoge char a[100]; // ←元からある部分 #endif // hoge_main_h_included_hogehoge これはむか~~しからインクルードガードと呼ばれ、 同じヘッダファイルが複数回includeされないようにする方法でござんす。 また、sub.cpp 4行目の  void sab(){ は、  void sub_write(){ の誤りですよね。 最後に、コンパイル環境不明ですがリンク順も要注意かな

yumichongu
質問者

お礼

皆様ありがとうございます。 私の考え方が少し違っていたみたいで使い方がおかしいようなので、新しく質問をさせていただきます。 また#4様のご指摘どおりvoid sabは誤りでした。

その他の回答 (3)

  • yosi_yosi
  • ベストアンサー率35% (165/468)
回答No.3

main.hでchar a[100]が宣言されているためです。 この状態だと、main.cppとsub.cpp両方でchar a[100]が定義されてしまうため、エラーとなります。(同じシンボル名が存在するため) 解決するためには、 main.hでは広域変数を宣言しない main.cppにてchar a[100]を宣言する sub.cppにてextern char a[]として、外部で宣言されているものを定義する とすれば大丈夫です。 本当は広域変数はできる限り使用せず、void sub_write(const char *a)などとしたほうが良いと思いますが...

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> ----------(main.h)---------- > char a[100]; これをmain.cppとsub.cppの二箇所からインクルードしているからです。 aの定義はどちらか一方で行い、main.hの中では外部宣言のみ(具体的にはexternをつける)にすれば、解決します。

  • Dooon
  • ベストアンサー率20% (36/180)
回答No.1

エラーメッセージの言っている通りです。 "main.h"の変数aは、main.cppで既に使われているためです。 sub.cppで再度変数aを使おうとしています。 関数subへ引数として変数aを渡せばよいような気がしますけれど。

関連するQ&A

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );

  • C++のファイル分割でのエラーについて

    最近VC2008でC++の勉強を始めたのですが、ファイル分割でLNK2005エラーというのが発生し、解消できません。 インクルードガードは行ったのですが、どうしたらよいのか分かりません。 ソースコードはこんな感じです。 //main.cpp #include "sub.h" #include "res.h" bool main(){ calcx(m_x); calcy(m_y); } //res.h 共有変数の宣言 #ifndef __RES_H #define __RES_H int m_x; int m_y; #endif //sub.h 関数のプロトタイプ宣言を行う void calcx(); void calcy(); //sub.cpp 関数の定義を記述する #include "res.h" void calcx(int x){ m_x = x + 100; } void calcy(int y){ m_y = y + 200; } エラー: 1>Main.obj : error LNK2005: "int m_x" (?m_x@@3HA) は既に sub.obj で定義されています。 1>Main.obj : error LNK2005: "int m_y" (?m_y@@3HA) は既に sub.obj で定義されています。 上記のようなエラーを解消するにはどうしたら良いのでしょうか。 何がおかしいのか指摘をお願いします。

  • C++のファイルの分割について教えてください。

    分割したプログラムの書き方を練習中なのですが、 下のようなプログラムを書いて、ビルドしようとしたら失敗します。 どこが悪いのか、教えていただけないでしょうか? (5)\test30\Debug\test30.exe : fatal error LNK1120: 外部参照 1 が未解決です。 1>test30 - エラー 2、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== //test30.cpp #include <iostream> #include "sub.h" int main(void) { std::cout<<"メインプログラムです。"<<std::endl; sub1(); sub2(); return 0; } ------------------------------------------------------------- //sub1.cpp #include <iostream> void sub1(void) { std::cout<<"サブ1です。"<<std::endl; } ------------------------------------------------------------- //sub2.cpp #include <iostream> void sub1(void) { std::cout<<"サブ2です。"<<std::endl; } --------------------------------------------------------------- //sub.h void sub1(void); void sub2(void);

  • 多重定義が起きている?--lnk2005エラー:VC++

    今つまずいている問題は、VC++2008環境下で、以下のような構造になっているプログラムにおいて、多重定義?されているのでコンパイルが通らないというものです。 ソースコードを載せることは大きすぎてできないので、問題となる部分の記述のみ抽出して書きます。 -------define.h---------- ・・・・(module.h内の関数に使われる型の定義など) --------------------------- -------module.h---------- #include "define.h" void mod_1(void){・・・} void mod_2(void){・・・} --------------------------- このように、2つのヘッダーファイルがあり、define.hをインクルードしてmodule.hを使うという構造です。 (一般的ではないようですが、module.h内にmod_1やmod_2の実体を書き込んでいます。) その中で、以下のようなcppソースファイルがあります。 -------Main.cpp---------- #include "module.h"   (他のMain.cpp内の関数の都合上、Main.cppでもmodule.hをインクルードしています。関係あるかもしれないと思い書きました。) int main(){ M(); N(); } ------------------------ -------M.cpp---------- #include "module.h" void M(void){ mod_1(); mod_2(); } ---------------------- -------N.cpp---------- #include "module.h" void N(void){ mod_1(); mod_2(); } ---------------------- とすると、コンパイルの結果は次のようになります。 1>N.obj : error LNK2005: "void __cdecl mod_1(void)" (?mod_1@@YAXXZ) は既に M.obj で定義されています。 1>N.obj : error LNK2005: "void __cdecl mod_2(void)" (?mod_2@@YAXXZ) は既に M.obj で定義されています。 多重定義や多重インクルードは起こしていないと思っていますが、M.cppとN.cpp内の定義が衝突する理由がわかりません。どなたか理由が思いつく方、教えていただけたら幸いです。お願いいたします!! ◆◆◆   ◆◆◆   ◆◆◆   ◆◆◆   ◆◆◆ ちなみに、たとえばMやNとまったく同じ「A.cpp」を作り、このように書いたとします。 -------A.cpp---------- #include "module.h" void A(void){ mod_1(); mod_2(); } ---------------------- そしてmain関数の中に、MやNと同様に『A();』を付け加えたとします。 すると、実行結果はこのようになります。 1>M.obj : error LNK2005: "void __cdecl mod_1(void)" (?mod_1@@YAXXZ) は既に A.obj で定義されています。 1>M.obj : error LNK2005: "void __cdecl mod_2(void)" (?mod_2@@YAXXZ) は既に A.obj で定義されています。 1>N.obj : error LNK2005: "void __cdecl mod_1(void)" (?mod_1@@YAXXZ) は既に A.obj で定義されています。 1>N.obj : error LNK2005: "void __cdecl mod_2(void)" (?mod_2@@YAXXZ) は既に A.obj で定義されています。 VC++はファイル名のアルファベット順にコンパイルするようですが、どちらにせよmain関数内で呼び出されていること以外何の関わりも無いはずのA、M、Nの中での出来事が、衝突する理由が、調べども思い当たりません。 お願いいたします。

  • 分割コンパイルの#defineについて

    分割コンパイルで ファイル1 #include <stdio.h> #define number 10 char string[number]; int main(void){ string[0]='a'; string[1]='b'; file_to(); return 0; } ファイル2 #include <stdio.h> #define number 10 extern char string[number]; void file_to(void){ /***何かの処理をする*****/ } って感じなんですけども、配列string の中身の値をdefineによって指定しているのですが、片方のdefineの値を変更する時、もう一つのdefineも手動で変更しています。関係するファイル数が多くなってくると大変なので、どれかのdefineの値を変化させたら自動的に他のdefineの値も変更するプログラムの組み方はありませんか? 質問がわかりにくいかも知れませんがよろしくお願いします。

  • 分割コンパイルの方法がわかりません‥(Studio.NET) →2

    先ほどはありがとうございました。 私の考え方が違っていたようで、 main.cpp で使っているグローバル変数をsub.cpp内で使いたい。 sub.cpp に記述している関数をmain.cppから呼び出したいときは どうしたらいいでしょうか? ヘッダファイルの書き方がわからないのです>< XPでStudio.NETでプログラミングしています。 よろしくお願いします><

  • 配列について

    初歩的な質問ですいませんが、質問よろしくお願いします。 ◎1----------------------------- #include<stdio.h> int main(void) { char ss[10]="AB"; printf("ss=%s\n",ss); return 0; } ------------------------------------ ◎2-------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss[0]='A'; ss[1]='B'; ss[2]=0; printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎3------------------------------- #include<stdio.h> #include<string.h> int main(void) { char ss[10]; strcpy(ss,"AB"); printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎4------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss="AB"; printf("ss=%s\n",ss); return 0; } ---------------------------------- 以上4つのプログラムで、◎2と◎3は正常に動くと理解できたのですが、何故、◎1は正常に動き、◎4は「'const char [3]' から 'char [10]' に変換できません。」といったようなエラーが出てしまうか分かりません。 教えていただければ嬉しいです。

  • error LNK2001について

    C++ の勉強中です。 error LNK2001問題がありました。問題点も分からないから、 分かった方に教えていただけないでしょうか? ソースも添付します。環境はVS2005 express edition まず、ヘッダファイルです。ファイル名は、myheader.h #ifndef __MYHEADER_H__ #define __MYHEADER_H__ #define includeshow(x) \ { \ s.show(x); \ } class Sample{ public: void show(char * parameter); }; extern Sample s; #endif //------------------------------------------------ 次に、Sample.cppです。 #include "myheader.h" #include <stdio.h> void Sample::show(char *parameter){ printf("in show func"); } //----------------------------------------------- 最後にTest.cppです。 #include "myheader.h" #include <stdio.h> int main(){ includeshow("ppppp"); } これで error LNK2001: 外部シンボル ""class Sample s" (?s@@3VSample@@A)" は未解決です。というエラーが出ています。 よろしくおねがいします。

  • 他の.CPPファイルに定義した関数を呼び出す方法について

    新規作成したプロジェクトに、 以前自分が作成した.cppファイルと.hファイルを そのまま使えないかと考えています。 (※仮にそのファイルの名前を "define.cpp" "define.h" とします) プロジェクトに新規ファイル main.cpp を作成して、 define.hをインクルードし、 以下のようなテストのプログラムを組みました。 ・../util/define.cpp---------------------- #include <iostream> #include "define.h" void test(){ std::cout<<"test."<<std::endl; } ・../util/define.h------------------------ #pragma once void test(); ・main.cpp---------------------------- #include "../util/define.h" int main(){  test();  return 0; } 上記のソースを VisualC++7.0 でビルドすると、 main.cppの3行目で以下のようなエラーが出ました。 > LNK2019: 未解決の外部シンボル "void __cdecl test(void)" が関数 _main で参照されました VisualC++で「既存項目の追加」という項目より、 実体の定義されたdefine.cppをプロジェクトに追加していないため 当然といえば当然なのですが・・・ C言語でいうところの<stdio.h>等みたいに、 わざわざプロジェクトにCPPファイルを追加しなくても 関数を呼び出せるようには出来ないのでしょうか? 全ての関数と処理をヘッダーファイルに記述すると解決ですが 物凄く見辛いのでそれは避けたいのです。 また、色々なPC間で使っているため(学校のPCなので)、 ツール自体のプロパティを弄らない方法があるのでしたら、 多少面倒でもそちらの方が好ましいです。 追加する方法があるかどうか、 あればその方法をご存じでしたら教えていただければ嬉しいです。 よろしくお願いします。

  • [VC++]ヘッダファイルからの関数コール

    Formのボタンクリックイベント(Form.h)から 別ファイル(.cpp)の関数をコールしたいのですがうまくいきません、 どのようにすればよいでしょうか?ご教授お願いします。 1> : error C2144: 構文エラー : 'void' は ')' によって先行されなければなりません。 1> : error C2059: 構文エラー : ')' //----- main1.h #include <stdio.h> #include "Form1.h" namespace A { void main1(); } //----- main1.cpp #include <stdio.h> #include "main1.h" using namespace A; void main1() { //処理 } //----- Form1.h #include <stdio.h> #include "main1.h" void main1(void); namespace A { public ref class Form1 : public System::Windows::Forms::Form { public: private: System::Void btn_Click(System::Object^ sender, System::EventArgs^ e) { //★クリックイベントからmain1の関数コールしたい main1(void); } }; }

専門家に質問してみよう