【问题标题】:cannot compile c codes using microsoft visual studio c++ 2008 express edition无法使用 microsoft visual studio c++ 2008 express edition 编译 c 代码
【发布时间】:2011-09-21 15:48:22
【问题描述】:

我有一个可以在 Linux 中使用 gcc 编译的 c 代码。但是当我尝试使用microsoft visual studio c++ 2008 express edition编译它时,使用ide,它显示错误

vec.obj : error LNK2005: _INIT_SETA already defined in a.obj
fatal error LNK1169: one or more multiply defined symbols found

我检查了头文件,它们都有预处理器保护,以防止头被多次包含,例如

#ifndef _vec_h_
#define _vec_h_

然后我尝试在visual studio命令提示符下编译它,

cl main.c

可以编译。问题是什么?

【问题讨论】:

  • 您是否尝试过清理解决方案/项目并重建它? Visual Studio 可能每次都以不同的顺序编译文件(或者您只更改一个需要重新编译的文件),所以您可能有旧的 obj 文件,其中定义已经存在?
  • 谢谢尼克!这真的很有帮助!我排除了所有文件,项目中只有main.c,现在可以编译了。谢谢Pratorian和Daniel,我想这确实是链接问题,但不知何故只有main.c就可以解决问题

标签: c++ c visual-studio-2008 compiler-errors


【解决方案1】:

I checked the header files, and all of them have the preprocessor guard to prevent the header to be included multiple times
这只防止预处理器在单个编译单元(cpp 文件)中多次包含单个头文件。因此,您仍然在两个 cpp 文件中都包含该标头,并且该标头定义了一个 _INIT_SETA 对象。如果标头仅包含声明而不包含定义,则可以避免该问题。 (没有函数代码,也没有全局变量。)

Hpp 文件:

#ifndef _vec_h_
#define _vec_h_
class vector {
    function();  //function prototype.  No definition
};  //class declaration.  No instantiation
extern vector myvector;   //variable declaration.  No instantiation
#endif //_vec_h_

Cpp 文件:

#include "vec.h"

vector::function() {} //function definition only in this cpp file

vector myvector; //variable instantiation only in this cpp file

唯一的例外通常是模板,它完全位于头文件中,链接器自己计算出来。

【讨论】:

    【解决方案2】:

    您发布的错误表明存在vec.ca.c(假设您没有尝试链接预先存在的目标文件),它们都定义了INIT_SETA。这是链接器错误,而不是编译错误。

    cl main.c 仅将文件编译为目标文件,没有进行链接。如果您尝试从命令行使用 (link.exe) 将所有目标文件链接在一起,您仍然会收到相同的错误。在错误中列出的两个文件中搜索INIT_SETA 符号的多个定义。

    一种可能的解决方案是在使用它的两个文件之一中声明它extern,然后这两个文件将共享同一个实例。

    如果两个文件都需要有私有副本,您应该取出所有出现在头文件中的extern INIT_SETA 声明(并将static 添加到每个源文件的定义中)。

    【讨论】:

      【解决方案3】:

      “找到一个或多个多重定义的符号”是链接器错误而不是编译器错误。当两个或多个目标文件包含相同符号的定义时,就会发生这种情况。在这种情况下,vec.obja.obj 都包含_INIT_SETA 符号的条目,因此您需要弄清楚vec.obja.obj 的来源是如何将_INIT_SETA 符号引入它们的各自的翻译单元(编译)。

      请注意,_INIT_SETA 是 C 标识符 INIT_SETA 的编译器生成的符号。也许INIT_SETA 的定义是通过宏扩展内联的?在这种情况下,INIT_SETA 的声明可能需要声明为static

      “多符号”问题的存在不会影响源文件的编译;而是链接步骤将失败,因为链接器不知道要链接哪个 _INIT_SETA 条目。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        • 1970-01-01
        • 2013-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多