为什么CRC32值需要-lz

3

我正在使用crc32(initial_crc_value,data,data_length);生成crc32值。如果我没有在链接器选项中使用-lz,那么我会收到链接器错误信息:

"未定义的参考 crc32"。

我没有包含任何zlib.h头文件。所以,在哪个头文件中声明了crc32()?为什么使用链接器选项-lz就足够编译呢?


crc32()函数在哪个文件中声明? - user4790894
1
@user4790894 声明和实现不是同一回事。如果你只是声明 crc32,那么你无法编译。你必须要有一个实现它的库,这个库在libz.so中。 - Eregrith
1个回答

4
首先,crc32()函数在zlib.h中声明(原型),并在zlib库中定义。因此,要使用crc32()函数,您需要包含头文件并链接库。
现在,回答您的问题,

1. 如果我没有在链接器选项中使用-lz,我会得到链接器错误

是的,因为在链接时,编译器将无法找到crc32()函数定义而不链接zlib库,该库包含函数定义。

2. 为什么链接器选项-lz就足以编译?

说实话,这还不足够,并且应该产生错误。但是,您的代码可以(编译)正常工作,是因为编译器依旧支持隐式声明函数。如果您启用适当的警告,编译器至少会警告您此问题。
关于函数的"隐式声明",情况是,如果编译器遇到一个函数调用,它尚未看到原型(换句话说,没有有关函数定义的信息),则假定该函数定义具有返回类型为int并接受任意数量的参数。您可以在相关答案上阅读更多信息。

如何在gcc中启用适当的警告? - user4790894
如果编译器将函数视为隐式声明,那么函数的实现是什么?它是否与libz.so链接? - user4790894
@user4790894 参见这篇文章。然而,大多数情况下,在编译语句中添加-Wall选项就足以警告您几乎所有可能的陷阱。 - Sourav Ghosh
即使使用隐式声明,如果您在编译时链接库,它仍将找到相同的函数。但是,如果函数签名不同(即返回除 int 以外的任何内容)且使用返回值,则会调用未定义行为 - Sourav Ghosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接