无法使用Microsoft visual studio c++ 2008 express版编译c代码

cannot compile c codes using microsoft visual studio c++ 2008 express edition

本文关键字:express 2008 编译 代码 c++ studio Microsoft visual      更新时间:2023-10-16

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

可以编译。有什么问题吗?

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

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

您发布的错误表明存在vec.ca.c(假设您不试图在预先存在的对象文件中链接),这两个定义了INIT_SETA。这是一个链接器错误,而不是编译错误。

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

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

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

"发现一个或多个乘法定义的符号"是链接器错误,而不是编译器错误。当两个或多个目标文件包含同一符号的定义时,就会发生这种情况。在这种情况下,vec.obja.obj不知何故都包含_INIT_SETA符号的条目,因此您需要弄清楚vec.obja.obj的源代码如何在各自的翻译单元(编译)中引入_INIT_SETA符号。

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

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