3つのソースファイルに対応する3つのモジュールに分割されているプログラムをコンパイルしようとしています:_a.c
_、_b.c
_、および_z.c
_。 _z.c
_にはmain()
関数が含まれ、_a.c
_および_b.c
_の関数を呼び出します。さらに、_a.c
_の関数は_b.c
_の関数を呼び出し、その逆も同様です。最後に、3つのモジュールで使用され、個別のヘッダーファイル_global.h
_で定義されているグローバル変数count
があります。
ソースファイルのコードは次のとおりです。
_a.c
_
_#include "global.h"
#include "b.h"
#include "a.h"
int functAb() {
functB();
functA();
return 0;
}
int functA() {
count++;
printf("A:%d\n", count);
return 0;
}
_
_b.c
_
_#include "global.h"
#include "a.h"
#include "b.h"
int functBa() {
functA();
functB();
return 0;
}
int functB() {
count++;
printf("B:%d\n", count);
return 0;
}
_
_z.c
_
_#include "a.h"
#include "b.h"
#include "global.h"
int main() {
count = 0;
functAb();
functBa();
return 0;
}
_
ヘッダーファイル:
_a.h
_
_#ifndef A_H
#define A_H
#include <stdio.h>
int functA();
int functAb();
#endif
_
_b.h
_
_#ifndef B_H
#define B_H
#include <stdio.h>
int functB();
int functBa();
#endif
_
_global.h
_
_#ifndef GLOBAL_H
#define GLOBAL_H
extern int count;
#endif
_
そして最後に、私のエラーを再現するmakefile
:
_CC = gcc
CFLAGS = -O3 -march=native -Wall -Wno-unused-result
z: a.o b.o z.o global.h
$(CC) -o z a.o b.o z.o $(CFLAGS)
a.o: a.c b.h global.h
$(CC) -c a.c $(CFLAGS)
b.o: b.c a.h global.h
$(CC) -c b.c $(CFLAGS)
z.o: z.c a.h global.h
$(CC) -c z.c $(CFLAGS)
_
これにより、オブジェクト_a.o
_、_b.o
_、および_z.o
_をコンパイルできますが、_make z
_とリンクすると、それらすべてで_undefined reference to 'count'
_が取得されます:
_z.o: In function `main':
z.c:(.text.startup+0x8): undefined reference to `count'
a.o: In function `functAb':
a.c:(.text+0xd): undefined reference to `count'
a.c:(.text+0x22): undefined reference to `count'
a.o: In function `functA':
a.c:(.text+0x46): undefined reference to `count'
a.c:(.text+0x5b): undefined reference to `count'
b.o:b.c:(.text+0xd): more undefined references to `count' follow
collect2: ld returned 1 exit status
_
この最小限の例では、実際のコードでエラーを再現することができたので、モジュール間の依存関係に問題があると思いますが、それを見つけることはできません。誰かが私を正しい方向に向けることができますか?
z.c
を変更します
#include "a.h"
#include "b.h"
#include "global.h"
int count; /* Definition here */
int main() {
count = 0;
functAb();
functBa();
return 0;
}
global.h
から、すべてのファイルは変数count
の-宣言を継承しますが、definitionはすべてのファイルにありません。
定義をファイルの1つにint count = some_value;
として追加する必要があります
定義済みカウントではなく、宣言済みカウントがあります。
extern
は宣言の一部であり、定義ではありません。
明示的に言うと、extern
はストレージクラス指定子であり、宣言で使用されます。
defineint count
ソースファイルのどこかに。
int count;
をz.cファイルに追加する必要があります。これは、ヘッダーファイルでextern
として変数を宣言するため、変数が別のファイルで宣言されることをコンパイラーに伝えますが、変数はまだ宣言されておらず、リンカーによって解決されます。
次に、変数をどこかで宣言する必要があります。