无法使用microsoft visual studio c ++ 2008 express edition编译c代码

时间:2011-09-21 15:48:23

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

我有一个c代码,可以使用gcc在Linux中编译。但是当我尝试使用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

可以编译。问题是什么?

3 个答案:

答案 0 :(得分:1)

“找到一个或多个乘法定义的符号”是链接器错误而不是编译器错误。当两个或多个目标文件包含同一符号的定义时,会发生这种情况。在这种情况下,vec.obja.obj都包含_INIT_SETA符号的条目,因此您需要弄清楚vec.obj和{{1}的来源每个符号都会在其各自的翻译单元(编辑)中引入a.obj符号。

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

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

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

相关问题