为何我的C++代码在VS/Eclipse中出现重复定义链接错误?
为什么C++代码在Visual Studio/Eclipse编译出错但Code::Blocks可以?
我使用默认配置为C++14的Visual Studio,代码如下:
// main.cpp #include "funciones.cpp" int main() { myMsj(); return 0; }
// funciones.cpp #include <iostream> // Declaration void myMsj(void); // Definition void myMsj(void) { std::cout << "llamada desde main\n"; }
编译器输出错误信息:
| Gravedad | Código | Descripción | Proyecto | Archivo | Línea | Estado suprimido |
|---|---|---|---|---|---|---|
| Error | LNK2005 | ya se definió "void __cdecl myMsj(void)" (?myMsj@@YAXXZ) en funciones.obj | prueba-1 | C:...\prueba-1\main.obj | 1 | |
| Error | LNK1169 | se encontraron uno o más símbolos definidos simultáneamente | prueba-1 | C:...\prueba-1\x64\Debug\prueba-1.exe | 1 |
该代码在Code::Blocks中可正常编译,但在Visual Studio和Eclipse C/C++中无法编译,请问这是为什么?我是否使用了VS/Eclipse中已弃用的声明/定义/调用语法?
问题原因
核心问题是函数重复定义,和语法弃用无关:
- Visual Studio、Eclipse这类IDE默认会将项目中所有
.cpp文件作为独立编译单元处理,每个.cpp文件会被单独编译成.obj目标文件。 - 你在
main.cpp中#include "funciones.cpp",这会把funciones.cpp的所有内容直接复制到main.cpp里,导致main.obj中包含了myMsj函数的定义;同时funciones.cpp本身也被编译成funciones.obj,里面也有myMsj的定义。 - 链接阶段,编译器发现两个目标文件里都有同一个函数的定义,就会抛出LNK2005(重复定义)和LNK1169(存在重复符号)错误。
为什么Code::Blocks可以编译?
大概率是Code::Blocks的默认配置中,没有将funciones.cpp加入项目的编译列表——它只编译了main.cpp,而main.cpp通过包含funciones.cpp获得了函数定义,所以不会出现重复定义的问题。但这属于非标准的项目配置,不是正确的C++工程实践。
解决方案
遵循C++工程的标准做法,用头文件声明函数,源文件实现函数:
- 创建
funciones.h头文件,添加函数声明并加上头文件保护(防止重复包含):
// funciones.h #ifndef FUNCIONES_H #define FUNCIONES_H void myMsj(void); #endif
- 修改
funciones.cpp,包含头文件并保留函数定义:
// funciones.cpp #include <iostream> #include "funciones.h" void myMsj(void) { std::cout << "llamada desde main\n"; }
- 修改
main.cpp,包含头文件而非源文件:
// main.cpp #include "funciones.h" int main() { myMsj(); return 0; }
这样每个编译单元只会包含函数声明,定义只存在于funciones.obj中,链接时就不会出现重复定义的问题。
内容的提问来源于stack exchange,提问作者OBI
相关产品推荐
相关产品推荐

