通过引用发送指针时出现意外输出
Unexpected output while sending a pointer by reference
所以,我尝试了一些东西,并决定有意地从应该 return 一个 int 的函数中删除一个 return 语句。
我的猜测是,该函数会 return 一个垃圾值,程序会正常终止。
但是,程序陷入了死循环。这是一个错误吗?还是我遗漏了什么?
我使用的编译器是 G++,GCC 版本 9.3.0 和 GNU-G++-17,以及 GNU-G++-14
#pragma GCC optimize("O1")
#include <iostream>
int f(int* &a)
{
std::cout << *a;
// return 0;
}
void solve()
{
int *p = new int{7};
f(p);
delete p;
}
int main()
{
solve();
}
编译器输出
777777777777777777777777777777777...(until it crashes...)
上面代码的ideone link : https://ideone.com/j9m24N
PS:- 它发生在 O1
、O2
、O3
、Ofast
的编译指示中,但不会发生在 O0
[= 中18=]
我知道我们应该提供一个 return 语句,但我想知道的是我们得到这个输出的原因。
Is this a bug ?
是的。这是您程序中的错误。
Or am I missing something?
是的。您缺少 return
语句。
why we are getting this output.
因为程序的行为是未定义的。这解释了 C++ 程序员需要了解的有关程序行为的所有信息,这就是我们在 C++ 语言的范围内所能了解的所有信息。
My guess was, that the function would ...
当程序的行为未定义时,您不能假设会有任何特定行为。
要了解特定编译程序的作用,您需要阅读编译器生成的程序集。我能够重现该行为,这里是一个简化:
f(int*&):
... instructions ...
solve():
... instructions ...
call f(int*&)
函数 f
不包含任何 ret
指令或任何其他会跳转到其他地方的指令。因此,执行将继续到恰好是函数 solve
的第一条指令的下一条指令。在 solve
结束时,我们调用 f
,这是我们开始的地方。我们最终得到无限递归。
所以,我尝试了一些东西,并决定有意地从应该 return 一个 int 的函数中删除一个 return 语句。
我的猜测是,该函数会 return 一个垃圾值,程序会正常终止。
但是,程序陷入了死循环。这是一个错误吗?还是我遗漏了什么?
我使用的编译器是 G++,GCC 版本 9.3.0 和 GNU-G++-17,以及 GNU-G++-14
#pragma GCC optimize("O1")
#include <iostream>
int f(int* &a)
{
std::cout << *a;
// return 0;
}
void solve()
{
int *p = new int{7};
f(p);
delete p;
}
int main()
{
solve();
}
编译器输出
777777777777777777777777777777777...(until it crashes...)
上面代码的ideone link : https://ideone.com/j9m24N
PS:- 它发生在 O1
、O2
、O3
、Ofast
的编译指示中,但不会发生在 O0
[= 中18=]
我知道我们应该提供一个 return 语句,但我想知道的是我们得到这个输出的原因。
Is this a bug ?
是的。这是您程序中的错误。
Or am I missing something?
是的。您缺少 return
语句。
why we are getting this output.
因为程序的行为是未定义的。这解释了 C++ 程序员需要了解的有关程序行为的所有信息,这就是我们在 C++ 语言的范围内所能了解的所有信息。
My guess was, that the function would ...
当程序的行为未定义时,您不能假设会有任何特定行为。
要了解特定编译程序的作用,您需要阅读编译器生成的程序集。我能够重现该行为,这里是一个简化:
f(int*&):
... instructions ...
solve():
... instructions ...
call f(int*&)
函数 f
不包含任何 ret
指令或任何其他会跳转到其他地方的指令。因此,执行将继续到恰好是函数 solve
的第一条指令的下一条指令。在 solve
结束时,我们调用 f
,这是我们开始的地方。我们最终得到无限递归。