我不太确定我是否理解为什么会出现问题
我们返回一个局部随机变量的引用
因为 C++ 标准规定如果您使用这样的函数是未定义的行为,并且您希望避免程序中出现未定义的行为。你的程序做什么应该由C++语言的规则决定,而不是随意的。
请注意,您返回的是指针而不是引用。但在这两种情况下都是未定义的行为。
那么通常的说法是,当函数被使用时,内存
变量phantom 在执行后不再可用
代码行int phantom = 4; 所以它不能被返回(至少这个
是我目前所理解的)。
这是一个以实现为中心的观点,可以帮助您理解问题。
尽管如此,区分程序的可观察行为和编译器产生该行为的内部技巧很重要。您甚至都不知道变量是否占用了任何内存。考虑到“as-if”规则和编译器优化,整个函数可能已被删除,即使行为已定义。这只是幕后可能真正发生的事情的一个例子。
但是,无论如何,这是未定义的行为,所以任何事情都可能发生。
那么问题是,为什么 C++ 标准没有为当您返回这样的指针然后尝试访问指针对象时的情况定义行为?答案是没有意义。由局部变量 phantom 命名的对象在函数返回时结束其生命周期。所以你会有一个指向不再存在的东西的指针,但它仍然是一个int*,并且取消引用非nullptr int* 应该产生一个int。这是一个矛盾,而 C++ 标准只是懒得解决这种毫无意义的情况。
注意这个观察是如何基于 C++ 语言规则的,不是编译器实现问题。
为什么在第一种情况下会出现编译错误,而在第二种情况下
万一一切正常??
这肯定是一个警告而不是一个错误,除非你的编译器选项使得每个警告都变成一个错误。编译器不能拒绝代码,因为it's not ill-formed。
尽管如此,您的编译器仍试图在第一种情况下提供帮助,因为它希望阻止您创建具有未定义行为的程序。
在第二种情况下,行为不是未定义的。按值返回意味着 copy 由您要返回的对象组成。副本是在原始文件被销毁之前制作的,然后调用者会收到该副本。这不是毫无意义的,也不是任何方面的矛盾,所以它是安全且明确的行为。
在第一种情况下,按值返回对您没有帮助,因为虽然指针本身被安全复制,但它的内容最终会导致未定义的行为。