链接期间对全局变量的未定义引用

fre*_*haf 16 c linker gcc compilation

我试图编译被划分成3个模块,对应于3个源文件的程序:a.c,b.c,和z.c.z.c包含main()函数,它调用函数a.cb.c.此外,函数a.c调用函数b.c,反之亦然.最后,有一个全局变量count,由三个模块使用,并在一个单独的头文件中定义global.h.

源文件的代码如下:

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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

z.c

#include "a.h"
#include "b.h"
#include "global.h"

int main() {
    count = 0;
    functAb();
    functBa();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

头文件:

a.h

#ifndef A_H
#define A_H

#include <stdio.h>

int functA();
int functAb();

#endif
Run Code Online (Sandbox Code Playgroud)

b.h

#ifndef B_H
#define B_H

#include <stdio.h>

int functB();
int functBa();

#endif
Run Code Online (Sandbox Code Playgroud)

global.h

#ifndef GLOBAL_H
#define GLOBAL_H

extern int count;

#endif
Run Code Online (Sandbox Code Playgroud)

最后,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)
Run Code Online (Sandbox Code Playgroud)

有了这个,我可以编译对象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
Run Code Online (Sandbox Code Playgroud)

我设法在这个最小的例子中重现了我的实际代码中的错误,所以我猜模块之间的依赖关系存在问题,但我无法发现它.谁能指出我正确的方向?

Moh*_*ain 19

改变你z.c

#include "a.h"
#include "b.h"
#include "global.h"

int count; /* Definition here */
int main() {
    count = 0;
    functAb();
    functBa();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

global.h,所有文件都继承变量声明,count但所有文件中都缺少定义.

您必须将定义添加到其中一个文件中 int count = some_value;

  • @Taozi不,它将使count成为局部变量。我们需要一个全球定义。 (2认同)

Sou*_*osh 7

您已声明计数,未定义计数.

extern 是声明的一部分,而不是定义.

显而易见,extern是存储类说明符并在声明时使用.

您需要在源文件中的某个位置定义 int count.


LPs*_*LPs 7

您必须添加int count;到您的 zc 文件中。这是因为在头文件中声明变量告诉extern编译器该变量将在另一个文件中声明,但该变量尚未声明并将由链接器解析。

然后你需要在某处声明变量。

  • 是的,这是恶魔般的。对所有初学者表示抱歉:) (5认同)