gpt4 book ai didi

c++ - Mac 和 Linux 中 C++ 的 const auto& 的不同行为

转载 作者:太空宇宙 更新时间:2023-11-04 05:37:37 25 4
gpt4 key购买 nike

我目前在 Mac 和 Linux 中面临不同的行为问题。我在文件 test_max.cpp 中有以下代码。

#include <iostream>
#include <algorithm>

float func(float a) {
float b = a;
return b;
}

int main() {
float a = 0.6, b = 1;

const auto& a1 = func(a);
const auto& b1 = func(b);
const auto& res1 = std::max(func(a), func(b));
const auto& res2 = std::max(a1, b1);

std::cout << "res1: " << res1 << std::endl;
std::cout << "res2: " << res2 << std::endl;
}

这就是我编译代码的方式。

g++ -std=c++11  -01 -o test_max test_max.cpp && ./test_max

在 Mac 上,它为 res1res2 返回相同的值 1。但是,在 Linux 上,它始终为 res1 返回 0。我不知道为什么。有人可以帮助我吗?

最佳答案

当您在不同的编译器下看到不同的行为时,您很可能处于未定义行为的领域(或者可能只是未指定的行为)。在这种情况下,未定义的行为来自于访问悬空引用 (res1)。

const auto& res1 = std::max(func(a), func(b));

此行将 res1 初始化为对 std::max 返回的任何内容的引用,设置悬空引用的可能性。先验的,这只是一种可能性;一些看起来相似的线条不会创建悬空引用。第一个要考虑的因素是最外层的函数 std::max。如果该函数按值返回(也称为返回临时值),则该临时值的生命周期将延长,以便 res1 不会悬空。然而,情况并非如此,因为它返回一个引用。不仅仅是任何引用,而是对其参数之一的引用。不过,只要返回的参数本身不是临时参数,这就可以了。唉,func() 按值返回,而不是按引用返回。所以我们的情况确实很糟糕。

  1. max 的参数是临时参数。
  2. max 返回对其参数的引用。

这就是 Lifetime of a temporary 第三个要点中描述的情况@cppreference.com。结果是一个悬空引用,访问它以打印其值会调用未定义的行为。

<小时/>

值得注意的是,添加另一个函数调用可以解决未定义的行为:

const auto& res1 = func(std::max(func(a), func(b)));

当然,如果 func 不是恒等函数,这会改变功能。但是,就未定义行为而言,最外层 func 返回的值是 func(b) 返回的临时值的拷贝。它是一个新的临时变量,立即绑定(bind)到引用变量,因此它的生命周期得到延长。一切都很好。

话又说回来,此行更典型的修复方法是删除&符号...
嗯,学习练习。

关于c++ - Mac 和 Linux 中 C++ 的 const auto& 的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55423740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com