includeをうまく処理するには?

解決


dac  2006-05-19 02:56:14  No: 61877

例えば、三つのファイルがあるとします。
一つ目は、main.cpp
二つ目は、main.h
三つ目は、sub.cpp
です。

main.cpp内の内容
#include "main.h"

void main()
{
  ...
  ...
  ...
}
#include "sub.cpp"

です。

main.hではmain.cppとsub.cppで使われる変数などが宣言されています。
これをビルドするとどうしてもsub.cpp内で使われている変数が宣言されていないというエラーがでます。
これは何がいけないのでしょうか?

どうかよろしくお願い致します。


dac  2006-05-19 02:58:02  No: 61878

ちなみにsub.cpp内ではmain.hをインクルードしてません。
インクルードするとある関数が再宣言されているというエラーがでるからです。


kure  2006-05-19 03:17:44  No: 61879

[main.cpp]
#include "main.h"

void main(){
...
}

//#include "sub.cpp" // <- ここでincludeしない

[sub.cpp]
#include "main.h"

...

ではいけない理由って何かあるのですか?
それとも単にコンパイルされるときの翻訳単位とかが理解できてないってことでしょうか?


kure  2006-05-19 03:20:14  No: 61880

>ではいけない理由って何かあるのですか?

これは

>インクルードするとある関数が再宣言されているというエラーがでるからです

が原因ということでしょうか?

であれば関数の宣言と定義が区別できていないか、
処理内容の違う同名の関数を定義しているのでしょう。

どちらがどうかってのはコードをみないとなんとも言えません。


KING・王  2006-05-19 05:27:36  No: 61881

もしかして、プロジェクトの中に、sub.cppが入っていませんか?
その場合、プロジェクトからsub.cppを削除してください。

とりあえず、以下の場合、VC6SP5で問題なくコンパイル、実行できました。
[main.h]
// Main.h
#include <stdio.h>

int     nTestMain;
short   sTestSub;

void subFunc( );

[main.cpp]
// Main.cpp
#include "main.h"

int main( void )
{
    nTestMain = 1;
  
    subFunc( );

    printf( "nTestMain = %d\n", nTestMain );
    printf( "sTestSub = %d\n", sTestSub );

    return 0;
}

#include "Sub.cpp"

[Sub.cpp]
// Sub.cpp

void subFunc( )
{
    sTestSub = 2;
}

[ビルド結果]
----構成: 20060518_01 - Win32 Debug----
コンパイル中...
main.cpp
リンク中...

20060518_01.exe - エラー 0、警告 0

もし、Sub.cppをプロジェクトに入っている場合
[ビルド結果]
----構成: 20060518_01 - Win32 Debug----
コンパイル中...
main.cpp
Sub.cpp
C:\20060518_01\Sub.cpp(5) : error C2065: 'sTestSub' : 定義されていない識別子です。
cl.exe の実行エラー

20060518_01.exe - エラー 1、警告 0


dac  2006-05-19 23:39:42  No: 61882

KING・王 さんありがとうございます。
すごいです!
エラーとれました。
ほんとありがとうございます。


kure  2006-05-20 20:29:38  No: 61883

本当にプロジェクトからはずすって解決策でいいんかいな?
そんなんするくらいなら.cppじゃなくて.hにするでもいいし、
includeの位置を見直すとかきちんと宣言をするとか、
いくらでももっとまともな対策があるはずなんだけどなぁ。

プロジェクトからはずしたらコンパイル対象じゃないように見えて
IDE使ってる意味があんましないんじゃないでしょうかね?


Ban  2006-05-20 20:57:42  No: 61884

プロジェクトからはずさなくても、ファイルの個別プロパティで
コンパイル対象から個別にはずすこともできますし…。
# コンパイル対象になってないことで更に他人を混乱させる可能性大。

includeと、定義/宣言の区別ができてないことは確認できたわけですが、
強引にエラーだけ取って見ただけだと思いますので、
きちんとCの勉強をして、まともに直すことを私もお勧めします。


dac  2006-05-22 23:17:08  No: 61885

そうなんですか!?
これでは本当に解決できたといえないんですか?

他のやり方があるならどうかご教授お願いします。


kure  2006-05-22 23:36:18  No: 61886

> 本当に解決できたといえないんですか?
「本当の解決」の定義によります。
「本当の解決」かどうかはわかりませんが、私はプロジェクトからはずすことによる不利益の方が大きいと判断しました。

> 他のやり方
まず、宣言と定義の仕方や違いなどをきちんと勉強してください。
C言語の入門書にも書いてあるはずです。
詳細なコードが提示されてもいない状態で教えてくれと言われても、
何をどう直すべきかの判断ができないので無理です。
それにヒントは既に提示していますよね?


REE  2006-05-22 23:41:00  No: 61887

>これでは本当に解決できたといえないんですか?

#include "sub.cpp"
これが何のために必要で、どういう働きをするのか説明できますか?

>他のやり方があるならどうかご教授お願いします。

kureさんの 2006/05/18(木) 18:17:44の発言の方法が一般的です。
その場合は、プロジェクトにsub.cppを戻しましょう。


KING・王  2006-05-23 07:15:17  No: 61888

すいません。
たしかに、私の示した方法は、無理やりエラーを回避しているだけで、
根本的な問題解決になっていませでした。

いや、、、どのファイルがコンパイル対象になっているかが
dacさんが思っているのと異なっていることを示したかったのですが、
全くの言葉足らずでした。
(というか、今読み返すと、全くそのような意図が読み取れない。。。orz)

#最近VSのようなIDEで開発されるため、コンパイルとリンクの違い等を
#よく分かっていない、また、.objファイルを知らない人が多いような気がするのですが。
#コマンドラインからのコンパイルや、makeファイルを自分で書いてのコンパイルしていた時代は、
#どのファイルをコンパイルしてどの.objを作成したり、
#またどのファイルをリンクして実行ファイルを作成するかなどを、
#みんな把握していたような気がするのですが。。。


REE  2006-05-24 19:39:13  No: 61889

KING・王さんの方法はある意味、正しいと思いますよ。
もとのソースを作った人(多分dacさんではない)は、
おそらく、コマンドラインでやっていて、
main.cppだけのコンパイルで実行ファイルが出来るように作ったのでしょう。
#  makeやバッチファイルを作らなかったor作れなかった

それを今回dacさんが総合環境でコンパイルしようとして失敗したと思われます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加