链接期间对全局变量的未定义引用
Undefined reference to global variable during linking
我正在尝试编译一个分为3个模块的程序,对应3个源文件:a.c
、b.c
和z.c
。 z.c
包含 main()
函数,它调用 a.c
和 b.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;
}
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
的 声明 ,但缺少 定义 来自所有文件。
您必须将定义添加到其中一个文件中 int count = some_value;
您声明计数,而不是定义计数。
extern
是声明的一部分,不是定义。
明确地说,extern
是存储-class 说明符并在声明时使用。
您需要在源文件的某处定义 int count
。
您必须将 int count;
添加到您的 z.c 文件中。
这是因为在头文件中声明变量 extern
告诉编译器该变量将在另一个文件中声明,但该变量尚未声明并将由链接器解析。
然后你需要在某处声明变量。
我正在尝试编译一个分为3个模块的程序,对应3个源文件:a.c
、b.c
和z.c
。 z.c
包含 main()
函数,它调用 a.c
和 b.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;
}
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
的 声明 ,但缺少 定义 来自所有文件。
您必须将定义添加到其中一个文件中 int count = some_value;
您声明计数,而不是定义计数。
extern
是声明的一部分,不是定义。
明确地说,extern
是存储-class 说明符并在声明时使用。
您需要在源文件的某处定义 int count
。
您必须将 int count;
添加到您的 z.c 文件中。
这是因为在头文件中声明变量 extern
告诉编译器该变量将在另一个文件中声明,但该变量尚未声明并将由链接器解析。
然后你需要在某处声明变量。