c - 我的头文件有什么问题?

标签 c gcc compiler-errors

我刚刚完成了一项学校作业,我在测试我的代码时遇到了问题,因为在运行 make packetize 之后我不断得到以下输出(这是教授给我们的 makefile)

cc     packetize.c   -o packetize
/tmp/ccJJyqF6.o: In function `block_to_packet':
packetize.c:(.text+0xb1): undefined reference to `crc_message'
collect2: ld returned 1 exit status
make: *** [packetize] Error 1

block_to_packet 在名为 packetize.c 的文件中定义,crc_messagecrc16.c 中定义(两者都包含 #include "data.h" 行)。 data.h 中也有crc_message 的函数标题 所有这些文件都在同一个目录中。在过去的一个半小时里,我一直在尝试编译它们,并且无休止地搜索谷歌,但无济于事。它与我读过的链接有关,我的导师没有教过这个,所以我不知道如何编译这些文件来测试它们的输出。谁能告诉我怎么了?

最佳答案

你的头文件绝对没问题。您遇到的是一个链接器错误:packetize.c 的编译运行没有问题,但是您正在尝试链接一个可执行文件文件 packetize(因为您没有提供 -c 选项,该选项声明“编译为 object 文件”)。可执行文件还需要来自 crc16.c 的编译代码。

要么您必须在编译器行中提供所有源代码:

cc packetize.c crc16.c -o myApp

或者你必须编译成单独的目标文件,最终链接在一起:

cc -c packetize.c -o packetize.o
cc -c crc16.c -o crc16.o
cc packetize.o crc16.o -o myApp

前者是您在一次性命令行中执行的操作,后者是 Makefile 通常执行的操作。 (因为如果您所做的只是修改 packetize.c,则不需要重新编译 crc16.c。在大型项目中,重新编译可能会花费大量时间。)

编辑:

教程时间。注意给定命令行中是否存在 -c 选项。

考虑:

// foo.c

int foo()
{
    return 42;
}

定义函数foo()的源文件。

// foo.h

int foo();

头文件声明函数foo()

// main.c

#include "foo.h"

int main()
{
    return foo();
}

源文件引用 foo()

在文件 main.c 中,include 使编译器知道,最终,在某处,将有函数 foo() 的定义,声明在 foo.h。此时编译器只需要知道该函数将存在,它不接受任何参数,并且它返回 int。这足以将源代码编译为目标代码:

cc -c main.c -o main.o

但是,它还不足以实际编译一个可执行文件:

cc main.c -o testproc   # fail of compile-source-to-exe
ld main.o -o testproc   # fail of link-object-to-exe

编译器被 promise (通过声明)foo() 的定义将存在,这对编译器来说已经足够了。

然而,链接器(在第一个示例中由 cc 隐式运行)需要该定义。可执行文件需要执行函数foo(),但在main.c 中找不到它。无法解析对 foo() 的引用。 “ Unresolved 引用错误”。

您需要一次性编译两个源文件...

cc foo.c main.c -o testproc    # compile-source-to-exe

...或编译 foo.c 并为链接器提供两个目标文件,以便它可以解析所有引用:

cc -c foo.c -o foo.o
ld foo.o main.o -o testproc    # link-objects-to-exe

Post Scriptum:如上图所示直接调用 ld 很可能不会像那样工作。链接需要一些额外的参数,cc 隐式添加这些参数——C 运行时支持、标准 C 库,诸如此类。我没有在上面的例子中给出这些参数,因为它们会混淆问题并且超出了问题的范围。

关于c - 我的头文件有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21747762/

相关文章:

c# - 视觉 C# 错误 : The type or namespace name 'Compression' does not exist in the namespace 'System.IO'

c++ - 无法在 Mac OSX (Yosemite) 上安装 RNNLIB (http ://sourceforge.net/p/rnnl/wiki/Home/)

c - 拆分字符串并使用索引调用所需的元素

C 修改结构体中的 const 成员

c - 在内核 OpenCL 中实现 FIFO 的最佳方法

c - 在结构中静态初始化数组

C 语言中可以有一个没有名字的函数吗?

c++ - GCC pragma 在源文件中添加/删除编译器选项

c++ - using 声明是否应该隐藏继承的虚函数?

oracle - Oracle函数编译错误PLS-00103(遇到符号 “SELECT”…)