web-dev-qa-db-ja.com

プログラムで複数のCファイルをコンパイルする

次の2つのファイルがあります。

file1.c

int main(){
  foo();
  return 0;
}

file2.c

void foo(){

 }

2つのファイルをコンパイルしてリンクして、file1.cfooを追加せずにextern関数を認識しますか?

プロトタイプを更新しました。

gcc file1.c file2.cスロー:警告:関数fooの暗黙の宣言。

16
mary

externは必要ありませんが、file1.cはfoo()が存在する宣言を参照する必要があります。通常、この宣言はヘッダーファイルにあります。

ヘッダーファイルを使用せずに前方宣言を追加するには、file1.cを次のように変更します。

int foo();  // add this declaration

int main(){
  foo();
  return 0;
}
7
chrisaycock

正しい方法は次のとおりです。

file1.c

#include <stdio.h>
#include "file2.h"

int main(void){
    printf("%s:%s:%d \n", __FILE__, __FUNCTION__, __LINE__);
    foo();
    return 0;
}

file2.h

void foo(void);

file2.c

#include <stdio.h>
#include "file2.h"

void foo(void) {
    printf("%s:%s:%d \n", __FILE__, __func__, __LINE__);
    return;
}

output

$
$ gcc file1.c file2.c -o file -Wall
$
$ ./file 
file1.c:main:6 
file2.c:foo:6 
$ 
31

あなたはcanですが、すべきではありません。

ヘッダーファイルfile2.hを使用します。

// file2.h

void foo(); // prototype for function foo()

それから加えて:

#include "file2.h" 

file1.c

コンパイルします:

$ gcc -Wall file1.c file2.c -o foo

一般的なルールとして、依存関係内のad hocプロトタイプではなく、各moduleinterfaceを定義するためにヘッダーファイルを使用する方が(より堅牢です)モジュール。これは、SPOT(Single Point of Truth)の原則として知られています。

6
Paul R

醜いですが、gccを使用すると、次のことができます。

gcc -include file2.c file1.c

-includeはプリプロセッサへのフラグで、file2.cの内容をfile1.cの最上部に含めます。そうは言っても、それは不適切な選択であり、最も単純なプログラムを除いてすべてが失敗します。

2
Dave