web-dev-qa-db-ja.com

リンク中のグローバル変数への未定義の参照

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
_

この最小限の例では、実際のコードでエラーを再現することができたので、モジュール間の依存関係に問題があると思いますが、それを見つけることはできません。誰かが私を正しい方向に向けることができますか?

15
freieschaf

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;として追加する必要があります

17
Mohit Jain

定義済みカウントではなく、宣言済みカウントがあります。

externは宣言の一部であり、定義ではありません。

明示的に言うと、externはストレージクラス指定子であり、宣言で使用されます。

defineint countソースファイルのどこかに。

7
Sourav Ghosh

int count;をz.cファイルに追加する必要があります。これは、ヘッダーファイルでexternとして変数を宣言するため、変数が別のファイルで宣言されることをコンパイラーに伝えますが、変数はまだ宣言されておらず、リンカーによって解決されます。

次に、変数をどこかで宣言する必要があります。

1
LPs