为什么 "int i" 有多个定义?
Why "int i" has multiple definitions?
我有两个文件如下:
Test1.h
#ifndef TEST_H
#define TEST_H
int i = 10;
#endif
Test2.cpp
#include <iostream>
#include "Test1.h"
int main()
{
std::cout << i << std::endl;
}
我知道我可以通过在 Test1.h
.
中使用 extern 或 const 来解决这个问题
但我的问题是"I don't understand the error"。
error LNK2005: "int i" (?i@@3HA) already defined in Test1.obj
error LNK1169: one or more multiply defined symbols found
int i
怎么可以有多个定义?
- 头文件包含保护。
- 当我包含头文件时,它应该意味着所有内容都被复制到
Test2.cpp
中,它应该变成:
Test2.cpp
#include <iostream>
int i = 10
int main()
{
std::cout << i << std::endl;
}
在包含所有内容后,此时头文件应该变得无关紧要了。
我的另一个问题是,如果我在头文件中用extern
声明int i
并将其包含在.cpp中,那么它是否是外部链接的一个例子?因为通常我已经看到两个 .c
或 .cpp
之间的外部链接,如 here 但如果您明确包含该文件,它仍然被视为 i
具有外部链接吗?
可能您正在尝试从两个翻译单元创建可执行文件。
您的错误表明该对象已在 Test1.obj 中定义。可能,您的程序是 Test1.obj+Test2.obj,并且两个文件包含相同的定义,具有外部链接。
每个编译单元(一个 .cpp 文件)单独生成自己的一组符号,然后由链接器链接在一起。
一个header文件"becomes"它包含的编译单元的一部分,它编译成一个object文件(.obj in Windows,.o in Unix 系统)
因此就像你在每个编译单元中定义了一个全局的'i'。
正确的解决方案(如您所知,如果您必须拥有全局)是在 header 中将其声明为 "extern",然后让一个编译单元实际定义它。
Include guards 仅防止相同的 header 在同一个编译单元中被包含两次,如果我包含 and 并且其中一个包含另一个,则可能会发生这种情况。
When I include the header file it should mean that everything gets copied in Test2.cpp and it should become:
是的,然后您在 Test1.cpp 中执行完全相同的操作(您没有向我们展示)。
因此,多个定义。
How can int i have multiple definitions?
具有定义的文件包含在多个翻译单元(cpp 文件)中。一个单元被编译成 object 文件 Test1.obj
。另一个单位的来源显示在您的答案中 (Test2.cpp
)。当您尝试 link 将 object 个文件放在一起时会显示错误。
- The header file has include guards.
这可以防止文件内容在单个翻译单元中重复。分开单位没有区别。
My other question is if I declare int i with extern in header file and include it in .cpp, then would it be an example of external linkage?
extern
明确地使 linkage 外部化。但即使没有 extern
,在命名空间范围内声明的变量默认也有隐式外部 linkage(也有例外)。这种情况下的区别在于 extern
变量声明不是定义,除非有初始化程序。
I can achieve external linkage without including header file i.e. with two .cpp files by making a variable extern in one .cpp and defining it in other and linker finds its definition. But if I have one header file with extern variable and include it in other .cpp does this count as external linkage?
外部声明如何在 cpp 文件中结束并不重要。无论它是否包含在 header 中,它都声明了一个具有外部 linkage.
的变量
您的项目中是否还有其他 Test1.cpp 也包含 Test1.h ?
如果没有,您是否对编译器进行了任何配置,以便它也将 .h 文件构建为目标文件?
原因可以是以上两个问题之一的答案。
我有两个文件如下:
Test1.h
#ifndef TEST_H
#define TEST_H
int i = 10;
#endif
Test2.cpp
#include <iostream>
#include "Test1.h"
int main()
{
std::cout << i << std::endl;
}
我知道我可以通过在 Test1.h
.
但我的问题是"I don't understand the error"。
error LNK2005: "int i" (?i@@3HA) already defined in Test1.obj
error LNK1169: one or more multiply defined symbols found
int i
怎么可以有多个定义?
- 头文件包含保护。
- 当我包含头文件时,它应该意味着所有内容都被复制到
Test2.cpp
中,它应该变成:
Test2.cpp
#include <iostream>
int i = 10
int main()
{
std::cout << i << std::endl;
}
在包含所有内容后,此时头文件应该变得无关紧要了。
我的另一个问题是,如果我在头文件中用extern
声明int i
并将其包含在.cpp中,那么它是否是外部链接的一个例子?因为通常我已经看到两个 .c
或 .cpp
之间的外部链接,如 here 但如果您明确包含该文件,它仍然被视为 i
具有外部链接吗?
可能您正在尝试从两个翻译单元创建可执行文件。
您的错误表明该对象已在 Test1.obj 中定义。可能,您的程序是 Test1.obj+Test2.obj,并且两个文件包含相同的定义,具有外部链接。
每个编译单元(一个 .cpp 文件)单独生成自己的一组符号,然后由链接器链接在一起。
一个header文件"becomes"它包含的编译单元的一部分,它编译成一个object文件(.obj in Windows,.o in Unix 系统)
因此就像你在每个编译单元中定义了一个全局的'i'。 正确的解决方案(如您所知,如果您必须拥有全局)是在 header 中将其声明为 "extern",然后让一个编译单元实际定义它。
Include guards 仅防止相同的 header 在同一个编译单元中被包含两次,如果我包含 and 并且其中一个包含另一个,则可能会发生这种情况。
When I include the header file it should mean that everything gets copied in Test2.cpp and it should become:
是的,然后您在 Test1.cpp 中执行完全相同的操作(您没有向我们展示)。
因此,多个定义。
How can int i have multiple definitions?
具有定义的文件包含在多个翻译单元(cpp 文件)中。一个单元被编译成 object 文件 Test1.obj
。另一个单位的来源显示在您的答案中 (Test2.cpp
)。当您尝试 link 将 object 个文件放在一起时会显示错误。
- The header file has include guards.
这可以防止文件内容在单个翻译单元中重复。分开单位没有区别。
My other question is if I declare int i with extern in header file and include it in .cpp, then would it be an example of external linkage?
extern
明确地使 linkage 外部化。但即使没有 extern
,在命名空间范围内声明的变量默认也有隐式外部 linkage(也有例外)。这种情况下的区别在于 extern
变量声明不是定义,除非有初始化程序。
I can achieve external linkage without including header file i.e. with two .cpp files by making a variable extern in one .cpp and defining it in other and linker finds its definition. But if I have one header file with extern variable and include it in other .cpp does this count as external linkage?
外部声明如何在 cpp 文件中结束并不重要。无论它是否包含在 header 中,它都声明了一个具有外部 linkage.
的变量您的项目中是否还有其他 Test1.cpp 也包含 Test1.h ?
如果没有,您是否对编译器进行了任何配置,以便它也将 .h 文件构建为目标文件?
原因可以是以上两个问题之一的答案。