在c++中,如果返回一个指针并立即解引用,这两个操作会被优化掉吗?

In C++ if a pointer is returned and immediately dereferenced, will the two operations be optimized away?

本文关键字:两个 操作 优化 引用 返回 如果 c++ 一个 指针      更新时间:2023-10-16

在c++中,如果我得到并返回一个变量的地址,调用者立即取消引用它,编译器会可靠地优化出这两个操作吗?

我问的原因是我有一个数据结构,我使用类似于std::map的接口,其中find()返回指向值的指针(迭代器),并返回NULL(没有微不足道的.end()等效),以指示未找到该值。

我碰巧知道被存储的变量是指针,所以返回NULL工作很好,即使我直接返回值,但似乎返回值的指针更一般。否则,如果有人试图在那里存储一个实际上是0的int值,数据结构会声明它不存在。

然而,我想知道这里是否有任何效率损失,因为编译器应该优化那些只是撤销彼此影响的动作。问题是,这两个是由一个函数返回分开的,所以它可能无法检测到它们只是撤销对方。

最后,如果有一个只返回值的私有成员函数和一个只接受值的地址的内联公共成员函数怎么办?这样,至少地址/解引用操作会一起发生,并且有更好的机会被优化出来,而find()函数的整个主体不是内联的。

<罢工>

<>之前私人:V _find(key) {...//几行…}公众:inline V* find(key) {返回&_find(关键);}std:: cout & lt; & lt;*找到(a_key); 之前

这将返回一个指向临时对象的指针,这是我没有想到的。与此类似的唯一方法是在_find()中进行大量处理,并在find()中执行最后一步并返回指针,以尽量减少内联代码的数量。


private:
W* _find(key) {
   ... // a few dozen lines...
}
public:
inline V* find(key) {
    return some_func(_find(key)); // last steps on W to get V*
}
std::cout << *find(a_key);

或者正如另一个回复者提到的,我们可以在原始版本中返回对V的引用(再次,不确定为什么我们第一眼就看不出这些琐碎的东西……看到讨论。)


private:
V& _find(key) {
   ... // a few dozen lines...
}

public:
inline V* find(key) {
    return &_find(key);
}
std::cout << *find(a_key);

_find返回V类型的临时对象。find然后试图采取临时的地址并返回它。临时对象不会持续很长时间,因此得名。所以_find返回的临时地址在得到地址后会被销毁。因此,find将返回一个指向先前被销毁的对象的指针,这是不好的。

这两种情况我都见过。这实际上取决于编译器和优化级别。即使它被内联了,我也看到过编译器不会优化它的情况。

查看它是否得到优化的唯一方法是实际查看反汇编。

你可能应该做的是创建一个手动内联它们的版本。然后对它进行基准测试,看看是否真的获得了明显的性能提升。如果不是,那么整个问题都没有意义。

您的代码(即使是在它的第二个化身)是坏的。_find返回一个V, find在返回地址之前立即销毁它。

如果_findV&返回给一个对象,该对象的生命期超过了调用(从而产生正确的程序),则解引用将是无操作,因为引用与机器码级别的指针没有什么不同。