c++ - 在 C++ 中使用内联函数的未指定输出

标签 c++ c++11 linker inline unspecified-behavior

我正在研究代码以了解 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.cpptest2 中被声明为 inline。 cpp,但不在 driver.cpp 中。根据第 7.1.2/4 段

[...] If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. [...]

不需要诊断”位意味着编译器(或链接器)可能会或可能不会报告违反此规则的错误。这意味着您必须非常小心地打破它。

关于c++ - 在 C++ 中使用内联函数的未指定输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16760983/

相关文章:

c++ - automake undefined reference

c++ - 如何使用 std::make_unique 函数和接口(interface)类?

c++ - 分解/分解函数的函数

c++ - 在类外定义的类 typedef

c++ - 如何在没有范围的情况下使用枚举类

c++ - 将 const 类对象传递给 std::function 和 std::bind 会导致编译错误

c - gcc-linux-gnueabi-arm 错误 undefined reference to `main'

c++ - 如何检查包含 utf8 文本的 std::string 在 Windows 中是否以大写字母开头?

c++ - C++ 能否定义宏将浮点文字重写为 double 文字或至少删除 f 后缀?

linker - 链接时:使用-l标志或仅将归档作为输入