我正在研究代码以了解 C++ 中的内部和外部链接。我想出了这样的代码,其输出似乎会根据链接的顺序而有所不同。
test1.cpp
#include<iostream>
using namespace std;
inline int c()
{
static int p=0;
p++;
return p;
}
void a()
{
cout<<"\nIn function a() , c = "<<c();
}
test2.cpp
#include<iostream>
using namespace std;
inline int c()
{
static int p=12;
p++;
return p;
}
void b()
{
cout<<"\nIn function b() , c = "<<c();
}
驱动.cpp
#include<iostream>
using namespace std;
void a();
void b();
int c();
int main()
{
b();
a();
a();
b();
cout<<"\nIn function main() = , c "<< c();
cout<<"\n";
}
输出 1 :-
when compiles as follows :-
bash#>g++ -c test1.cpp
bash#>g++ -c test2.cpp
bash#>g++ -c driver.cpp
bash#>g++ -o out driver.o test1.o test2.o
bash#>./out
In function b() , c = 1
In function a() , c = 2
In function a() , c = 3
In function b() , c = 4
IN main() , c = 5
在上面的输出中,编译器正在考虑在 test1.cpp 中定义的 c()
输出 2:- 链接时更改 test1.o 和 test2.o 的顺序。
bash#>g++ -o out driver.o test2.o test1.o
In function b() , c = 13
In function a() , c = 14
In function a() , c = 15
In function b() , c = 16
IN main() , c = 17
在上面的输出中,编译器正在考虑 test2.cpp 中定义的 c()
当我对代码做了一些小改动时,我感到很困惑,具体如下:-
1) 如果我不在函数 a() [test1.cpp] 中调用 c() 并且在函数 b()[test2.cpp] 中调用 c()
//test1.cpp changes
void a()
{
cout<<"\nIn function a() , c = "; // not calling c()
}
//test2.cpp changes
void b()
{
cout<<"\nIn function b() , c = "; // not calling c()
}
链接时出现以下错误:-
bash#>g++ -o out driver.o test1.o test2.o
driver.o: In function `main':
driver.cpp:(.text+0x1f): undefined reference to `c()'
collect2: ld returned 1 exit status
2) 如果我在文件的任何一个中调用 c(),即在 test1.cpp 或 test2.cpp 中,那么我不会收到链接器错误。
谁能帮我理解这种行为。
提前致谢。
最佳答案
你的程序有未定义的行为,因为它违反了一个定义规则。两个不同的翻译单元正在定义一个具有相同名称和签名但主体不同的函数。
根据 C++11 标准的第 3.2/6 段:
[...] Given such an entity named
D
defined in more than one translation unit, then— each definition of
D
shall consist of the same sequence of tokens; and[...]
您的程序也是格式错误的,因为函数 c()
在 test1.cpp
和 test2 中被声明为
,但不在 inline
。 cppdriver.cpp
中。根据第 7.1.2/4 段
[...] If a function with external linkage is declared
inline
in one translation unit, it shall be declaredinline
in all translation units in which it appears; no diagnostic is required. [...]
“不需要诊断”位意味着编译器(或链接器)可能会或可能不会报告违反此规则的错误。这意味着您必须非常小心地打破它。
关于c++ - 在 C++ 中使用内联函数的未指定输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16760983/