c++ - 在 Linux 上编译 C++ 代码。需要使用intel/icpc编译器。错误: "multiple definitions" related to inerited class

标签 c++ linux inheritance compiler-errors icc

我正在尝试在 Linux 集群上编译大型 C++ 代码(也有一些 C 文件),并在使用 g++ 编译的 Mac 上运行了一段时间。在集群上,我必须使用 gcc/4.7.2 或 intel/icpc(集群上还有其他软件仅适用于这两个编译器)。我是处理编译/链接问题的新手,所以没有什么建议/提示是太简单的。

几天前我在这里发布了一个关于使用 gcc/4.7.2 的问题。我一直没能解决这个问题,所以现在尝试icpc。事情进展得出奇的顺利,但有一个问题我无法解决。

问题是我收到与“多个定义”相关的错误。这些与继承的类中看似虚函数相关联。这段代码不是我写的。有一个基类 (Solver3)、一个派生类 (Solver2) 和另一个派生类 (Solver1)。这些类(class)求解矩阵方程。我无法判断哪个函数出了问题,因为错误输出非常神秘(见下文;我没有名为“_fileno”的函数,并且在网上找不到该术语的任何通用定义)。但问题函数可能是 SolveWithSolver2,因为它是 Solver1 类中唯一的函数。我不知道它出了什么问题。

就 C++ 知识而言,这有点超出了我的理解范围,而且我很可能犯了一些初学者的错误。在过去的几天里,我一直使用谷歌搜索旧的论坛帖子。我尝试过重命名似乎有问题的函数,我尝试过内联它。我犯了同样的错误。代码非常大,而且只有一小部分是我写的,所以我不能发布太多内容。我会发布看起来相关的内容,如果有帮助的话可以添加内容。

以下是我遇到的错误类型,从第一个错误开始(我没有发布所有输出):

/code/libraries/libsolver.a(Solver1.o): In function _fileno(_IO_FILE*)': Solver1.cpp:(.text+0x0): multiple definition of_fileno(_IO_FILE*)' main.o:main.cpp:(.text+0x1bc0): first defined here

/code/libraries/libsolver.a(Solver2.o): In function _fileno(_IO_FILE*)': Solver2.cpp:(.text+0x0): multiple definition of_fileno(_IO_FILE*)' main.o:main.cpp:(.text+0x1bc0): first defined here

/code/libraries/libsolver.a(Solver3.o): In function _fileno(_IO_FILE*)': Solver3.cpp:(.text+0x0): multiple definition of_fileno(_IO_FILE*)' main.o:main.cpp:(.text+0x1bc0): first defined here

...等等

这是 Solver1 header 代码:

#ifndef SOLVER1
#define SOLVER1
#include "Solver2.h"
#include "ErrorHandler.h"
#ifdef SOLVER2

namespace code {
  class Solver1 : public Solver2 {
    public:
      Solver1( );

    //protected:
      virtual void SolveWithSolver2( Matrix& A,
                                     std::vector<double>& b,
                                     std::vector<double>& x,
                                     double tolerance );

    private:
      double pivot;
  };
} 
#endif
#endif

这是 Solver2 header 代码:

#ifndef SOLVER2_H
#define SOLVER2_H
#include "Solver3.h"
#include "helper.h"
#ifdef SOLVER2

namespace code {
  class Solver2: public Solver3 {
    public:
      Solver2 ();

    //protected:
      virtual void SolveWithSolver2(Matrix& A,
                                     std::vector<double>& b,
                                     std::vector<double>& x,
                                     double tolerance) = 0;

    private:
      virtual void SolveEquation(Matrix& A,
                                       std::vector<double>& b,
                                       std::vector<double>& x,
                                       stl_index unknowns);

      double Residual(const Matrix& A,
                              const std::vector<double>& b,
                              std::vector< double >& x);

      double Calculate(const SparseMatrix& A,
                                  const std::vector<double >& b,
                                  const std::vector< double >& x);

      double residual;
  };
} 
#endif
#endif 

回复雅各布: 输出:

"grep _fileno" /usr/include/* -R

/usr/include/bits/dirent.h:#define d_fileno d_ino /* Backwards compatibility. */ grep: warning: /usr/include/c++/4.3/x86_64-suse-linux/32: recursive directory loop

/usr/include/dirent.h:#if (defined __USE_BSD || defined __USE_MISC) && !defined d_fileno /usr/include/dirent.h:# define d_ino d_fileno /* Backward compatibility. */ /usr/include/lcms.h:# define fileno _fileno /usr/include/libdwarf/libdwarf.h: Dwarf_Unsigned * /*ret_fileno*/, /usr/include/libio.h:#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */ /usr/include/libio.h: int _fileno; /usr/include/linux/coda.h: u_int32_t d_fileno; /* file number of entry */ /usr/include/linux/mtio.h: __kernel_daddr_t mt_fileno; /* number of current file on tape */ /usr/include/sys/mtio.h: __daddr_t mt_fileno; /* Number of current file on tape. */ /usr/include/X11/Xw32defs.h:#define fileno _fileno

编辑:

使用 Jakob 关于编译器标志的建议(添加 -Wl 和 -z)到我的选项中,我的错误输出变得更加清晰;我得到了文件名、行号和特定错误。

我现在已经处理了这个问题,因为我可以编译该库。但说实话,我真的不知道为什么编译器一开始会提示或者为什么我的解决方案有效。这个问题涉及预处理器指令,我承认我对此知之甚少。如果有人愿意猜测问题是什么,那么了解一下会很有趣。我从来没有遇到过需要“;”的情况在之前的预处理器指令中。

这就是“固定”的事情(对粗体、大文本感到抱歉;似乎无法将其关闭):

define SOLVER_C_CONVERSION;

void __cdecl;

endif

这是出现问题时的样子:

define SOLVER_C_CONVERSION void __cdecl

endif

现在我已经解决了这个问题,我还有一个库需要处理。它抛出了 g++ 以前忽略的各种错误。如果我解决不了的话,今天晚些时候我可能会再次打扰你们。我很确定问题出在我的 makefile 上。

最佳答案

要解决多重定义的问题,第一步可能是

tracking down the include dependencies ,

使用“-M”或“-H”编译器标志, 例如:

gcc -H {use correct include flags here: -I$( include path)  } -c Solver1.cpp 

这将向您显示依赖关系树(自上而下阅读)

然后您就可以找出哪个文件定义了 _fileno 符号。
(例如,使用 grep 命令)

最后你可以尝试理解为什么 _fileno 被定义多次。

如果您想要更好的依赖项输出,通常可以尝试使用 doxygen 生成包含依赖项。


或者,作为解决方法,您可以使用以下链接标志,这将防止编译过程在多个定义的情况下失败:

-Wl,-z,multiple

关于c++ - 在 Linux 上编译 C++ 代码。需要使用intel/icpc编译器。错误: "multiple definitions" related to inerited class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17788165/

相关文章:

Linux >2.6.33 : could sendfile() be used to implement a faster 'cat' ?

c++ - COM-扩展“接口(interface)”?

c++ - 一个模板类如何继承另一个模板类?

c++ - 合并排序 - 堆栈损坏错误

c++ - 在 MFC 中显示 unicode 字符串

c++ - 更改比较函数以根据配对 vector 的第二个条目对绘图进行排序

linux - 从 glusterfs 缓存中删除文件(硬链接(hard link))

mysql - 如何在shell中使用mysql字段

c++ - 指针 vector ,继承

c++ - 旧 C++ 编译器中的防护