为什么"int i"有多个定义?
Why "int i" has multiple definitions?
我有两个文件如下:
测试1.h
#ifndef TEST_H
#define TEST_H
int i = 10;
#endif
测试2.cpp
#include <iostream>
#include "Test1.h"
int main()
{
std::cout << i << std::endl;
}
我知道我可以通过在 Test1.h
中使用 extern 或 const 来解决这个问题。
但我的问题是"我不明白错误"。
错误 LNK2005:"int i"(?i@@3HA)已在 Test1.obj
中定义 错误 LNK1169:找到一个或多个乘法定义的符号
int i
如何有多个定义?
- 头文件具有包含保护。
- 当我包含头文件时,它应该意味着所有内容都被复制到
Test2.cpp
中,它应该变成:
测试2.cpp
#include <iostream>
int i = 10
int main()
{
std::cout << i << std::endl;
}
在包含所有内容后,头文件此时应该变得无关紧要。
我的另一个问题是,如果我在头文件中声明带有extern
的int i
并将其包含在.cpp中,那么它会是外部链接的一个例子吗?因为通常我已经看到两个.c
或.cpp
之间的外部链接,就像这里一样,但是如果您明确包含该文件,它是否仍然被视为具有外部链接i
?
每个编译单元(.cpp文件)单独生成自己的符号集,然后通过链接器将这些符号链接在一起。
头文件"成为"它所包含的编译单元的一部分,编译为目标文件(Windows中的.obj,Unix系统中的.o)
因此,就像您在每个编译单元中定义了一个全局"i"。正确的解决方案(如您所知,如果您必须有一个全局)是在标头中将其声明为"extern",然后让一个编译单元实际定义它。
包含保护只能防止同一标头在同一编译单元中包含两次,如果我包含并且其中一个包含另一个,则可能会发生这种情况。
int i 怎么能有多个定义?
具有定义的文件包含在多个翻译单元(cpp 文件)中。一个单元被编译到目标文件Test1.obj
中。另一个单元的来源显示在您的答案中(Test2.cpp
)。当您尝试将目标文件链接在一起时,将显示此错误。
- 头文件具有包含保护。
这可以防止文件的内容在单个翻译单元中重复。分开单位没有区别。
我的另一个问题是,如果我在头文件中使用 extern 声明 int i 并将其包含在.cpp中,那么它会是外部链接的一个例子吗?
extern
使链接显式外部。但即使没有extern
,在命名空间作用域中声明的变量也默认具有隐式的外部链接(也有例外)。这种情况的区别在于,除非存在初始值设定项,否则extern
变量声明不是定义。
我可以在不包含头文件的情况下实现外部链接,即通过在一个.cpp中创建一个变量 extern 并在另一个中定义它来实现两个.cpp文件,链接器找到它的定义。但是,如果我有一个带有 extern 变量的头文件并将其包含在其他.cpp这算不算外部链接?
外部声明如何最终出现在 cpp 文件中并不重要。无论它是否包含在标头中,它都会声明一个具有外部链接的变量。
可能您正在尝试从两个翻译单元创建可执行文件。
您的错误表明该对象已在 Test1.obj 中定义。可能,你的程序是Test1.obj+Test2.obj,两个文件包含相同的定义,具有外部链接。
您的项目中还有其他 Test1.cpp 也包含 Test1.h 吗?
如果没有,您是否对编译器进行任何配置,以便它也将 .h 文件构建为目标文件?
原因可能只是上述两个问题之一的答案。
当我包含头文件时,它应该意味着所有内容都被复制到 Test2 中.cpp它应该变成:
是的,然后你在 Test1 中做了完全相同的事情.cpp(你没有向我们展示)。
因此,多个定义。
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
- 在标准中,模板参数的语法在哪里定义,例如,'std::function<int(char)>'?
- 当我尝试定义这个向量时<pair<int , pair<int, int> > > vp(n)
- 定义 uint= "unsigned int" 没有像我在 Visual Studio 中使用 nvcc 时预期的那样应用
- C++ std::vector<int> 体系结构的未定义符号 x86_64:
- 我可以使用常量定义数组的长度,那么为什么 int d[b] 不起作用呢?
- 如何定义int[][26]类型的变量
- 从 int 显式转换为用户定义的类 c++
- 对'cv::VideoCapture::VideoCapture(int)的未定义引用
- 是否打印指向已定义 int 的成员指针
- 编译Qt项目给出了对运算符delete(void*,unsigned int)的未定义引用
- 从emxArray_uint8_T检测到错误:.text+0xc1):未定义对"emxInit_uint8_T1(emxArray_uint8_T**, int)"的引用?
- 对 'i2c_smbus_read_word_data(int, 无符号字符)的未定义引用
- 定义.cpp中常数int/char*
- 处理代码重新定义int类型(uint16_t,int16_t等),并不喜欢它
- 有没有办法通过'greater/lesser than'而不是"="来定义'int'?
- 将定义 int 传递给函数作为参数
- types.h中的内容——编译器在哪里定义int、带符号int和其他值的宽度
- 错误 LNK2005:已在 functions.obj 中定义"int __cdecl number(void)" (?number@@YAHXZ)
- 使用winbgim库重新定义int右错误