1

在分析另一家公司提供的一些库代码时,我们遇到了奇怪的结构(可能是错误)。在头文件中,一个函数被声明为:

int funct(type1 var1, type2 var2, void* usr_arg);

(抱歉笼统的命名。NDA)但是在源文件中同名的函数被定义为:

int funct(type1 var1, type2 var2, long usr_arg)
{
    // code goes here;
}

最奇怪的是,在使用提供的 makefile 进行编译时,一切正常。然而,当我们尝试配置 eclipse 项目时,它拒绝编译,并指向我们上面提到的两个函数头。

在我们的例子中使用的编译器是 ubuntu 下的 gcc,但是这个库应该也可以在 windows 下工作。我们怎样才能让 gcc 接受这个怪物呢?

4

3 回答 3

1

这并不奇怪,Makefile 可能会将一些标志传递给 gcc 以忽略它,或者只是发出警告,而 eclipse 项目没有,或者可能是 eclipse 项目编译器标志更严格。无论如何,我建议您更改函数声明以匹配其定义(或相反,具体取决于函数实际期望的内容),错误就会消失。

于 2012-10-10T12:19:47.880 回答
1

如果定义,例如

 int funct(type1 var1, type2 var2, long usr_arg)
 {
  // etc
 }

没有出现在包含标头声明的文件中

 int funct(type1 var1, type2 var2, void* usr_arg);

GCC 编译器通常找不到任何错误。

我建议使用最近的 GCC(即 GCC 4.6 或 4.7)的链接时间优化能力,即在编译和链接时都传递-flto标志(带有一些优化标志)。

我不建议使用-fltowith gcc-4.5; 你真的想要至少 GCC 4.6

实现这一目标的一种可能方法是运行make CC='gcc -Wall -flto -O2';这可能会发现该错误。

请注意,这-flto会减慢构建时间,因为在编译每个源文件以及将每个增强的目标文件链接到可执行文件或库时都会进行一些优化

如果您的代码库足够重要,您可以考虑为此目的开发 GCC 的MELT扩展(MELT 是扩展 GCC 的高级域特定语言)。

于 2012-10-10T12:19:50.613 回答
1

我建议修复源(假设:它只是发生这种情况的有限数量的位置)。假设该函数确实是用指针调用的(如在声明中),您可以更改定义,如

int funct(int var1, int var2, void* usr_arg1) {
    long usr_arg = (long) usr_arg1;
    // code goes here;
}
于 2012-10-10T12:31:38.460 回答