【问题标题】:Compiler/Linking Error: Freedup编译器/链接错误:Freedup
【发布时间】:2009-12-07 21:47:06
【问题描述】:

我一直在尝试编译一个用于硬链接重复文件的程序,称为 freedup。我确实尝试向程序的作者/维护者发送电子邮件,但已经很长时间了,我还没有收到他的任何回复。

我正在尝试使用最新稳定版本的 gcc (3.4.4-999) 和 make (3.81-2) 从 cygwin 环境编译程序。我试过删除所有目标文件并运行make,但总是出现以下错误:

freedup.o:在函数'main'中:
/home/[user]/freedup-1.5/freedup.c:1791:未定义对“_hashed”的引用
collect2: ld 返回 1 个退出状态 make: * * * [freedup] 错误 1

我确实查看了源代码,发现“散列”函数是一个内联函数(我认为不必在源文件之外声明它......但这正是我从中收集到的一些初步的谷歌搜索)。

如果有人愿意尝试在 Windows 环境中编译此程序并有任何运气,我将不胜感激。谢谢

源文件的直接链接是:http://freedup.org/freedup-1.5-3-src.tgz

【问题讨论】:

  • 不知道编译,但我使用 perl 脚本执行实际任务(硬链接重复项):cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/… - 也许在 Cygwin 下也可以?
  • 您链接到的源代码使用 cygwin 和 gcc 3.4.4 为我构建得很好
  • 尝试删除inline ...并希望编译器将其内联:)
  • @karoberts 你用的是什么windows和cygwin版本?

标签: c linker compiler-errors inline-functions


【解决方案1】:

我对使用“#include <linux/stat.h>”而不是“#include <sys/stat.h>”的代码印象深刻。我也对 version.h 文件包含的代码不感兴趣:

-e #define VERSION "1.5-3"

(该文件由命令生成 - 'echo -e '#define...' > version.h'。呃!)

如果您将功能更改为:

inline int hashed(const char*s)
{
    int returnval=atoi(s);

    if(returnval>2) returnval=2;
    if(returnval<0) returnval=0;
    return returnval;
}

到:

static
inline int hashed(const char*s)
{
    int returnval=atoi(s);

    if(returnval>2) returnval=2;
    if(returnval<0) returnval=0;
    return returnval;
}

(并修复上面提到的其他问题),然后它在带有 GCC 的 MacOS X 10.6.2 上编译 “i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) (dot 1)”。

测试代码在随机点上失败,因为它假定 /bin/touch 中的触摸(在 MacOS X 上是 /usr/bin/touch)。还有很多关于“函数返回类型时忽略类型限定符”的警告,因为“auto.h”将 4 个函数定义为返回“const int”(对于“int”的各种伪装),以及在结构中的函数指针中相同的标题。

我想这归结为作者的经验不足 - 或者测试的平台不足。 version.h 命令不需要使用制表符(我相信 '-e' 是在命令行中扩展 '\t' 符号 - 应修复 Makefile 以省略 '-e' 和用一个简单的空白替换“\t”。

标准 C99 中“inline”的行为很有趣:

6.7.4 函数说明符

语法

函数说明符:

    inline

约束

函数说明符只能用于函数标识符的声明中。

具有外部链接的函数的内联定义不应包含 具有静态存储持续时间的可修改对象,并且不应包含对 具有内部链接的标识符。

在托管环境中,内联函数说明符不应出现在声明中 主要的。

语义

使用内联函数说明符声明的函数是内联函数。这 函数说明符可能出现多次;行为与出现时相同 只有一次。使函数成为内联函数表明对该函数的调用应为 尽可能快。118) 此类建议的有效程度是 实现定义。119)

任何具有内部链接的函数都可以是内联函数。对于具有外部功能的 链接,以下限制适用: 如果函数声明为内联 函数说明符,那么它也应该在同一个翻译单元中定义。如果所有的 翻译单元中函数的文件范围声明包括内联函数 没有 extern 的说明符,则该翻译单元中的定义是内联的 定义。内联定义不为函数提供外部定义, 并且不禁止在另一个翻译单元中进行外部定义。内联定义 提供了外部定义的替代方案,翻译人员可以使用它来实现 在同一个翻译单元中对函数的任何调用。未指定是否调用 函数使用内联定义或外部定义。120)

118) 例如,通过使用通常的函数调用机制的替代方法,例如“内联” 替代''。内联替换不是文本替换,也不会创建新函数。 因此,例如,在函数体中使用的宏的扩展使用 它在函数体出现时的定义,而不是函数被调用的位置;和 标识符指的是正文出现的范围内的声明。同样,该函数具有 单个地址,不管除了外部出现的内联定义的数量 定义。

119) 例如,一个实现可能永远不会执行内联替换,或者可能只执行内联 在内联声明范围内对调用的替换。

120) 因为内联定义不同于相应的外部定义和任何其他定义 其他翻译单元中对应的内联定义,所有对应的对象都有静态存储 持续时间在每个定义中也是不同的。

【讨论】:

  • 在所有方面都正确。内联函数很棘手。如果你编译时没有优化,并且编译器没有内联你的函数,那么如果你不放 extern inline foo(); 你会得到一个链接错误。在一个 .c 文件中强制发出非内联定义。
【解决方案2】:

Jonathan Leffler 为 freedup 1.5.3 提供了答案:在散列函数上添加“静态”或删除“内联”。 (您可能应该接受这个答案。)

freedup 1.6-* 根本无法在 Cygwin 上编译:

socket.c:20:26: fatal error: net/ethernet.h: No such file or directory

此文件在 Cygwin 中不存在。

【讨论】:

    猜你喜欢
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多