在C++;如果返回指针并立即取消引用,这两个操作会被优化掉吗? < >在C++中,如果得到并返回变量的地址和调用方,然后立即取消它,编译器会可靠地优化这两个操作吗?

在C++;如果返回指针并立即取消引用,这两个操作会被优化掉吗? < >在C++中,如果得到并返回变量的地址和调用方,然后立即取消它,编译器会可靠地优化这两个操作吗?,c++,pointers,compiler-construction,compiler-optimization,C++,Pointers,Compiler Construction,Compiler Optimization,我问这个问题的原因是我有一个数据结构,在这个结构中,我使用了一个类似于std::map的接口,其中find()返回一个指向某个值的指针(迭代器),并返回NULL(没有与之等价的.end()来表示尚未找到该值) 我碰巧知道存储的变量是指针,因此即使我直接返回值,返回NULL也可以,但返回指向该值的指针似乎更为一般。否则,如果有人试图在那里存储一个实际为0的int,那么数据结构会声称它不在那里 然而,我想知道这里是否有效率上的损失,因为编译器应该优化那些只会撤销彼此影响的操作。问题是这两个函数被一个

我问这个问题的原因是我有一个数据结构,在这个结构中,我使用了一个类似于std::map的接口,其中find()返回一个指向某个值的指针(迭代器),并返回NULL(没有与之等价的.end()来表示尚未找到该值)

我碰巧知道存储的变量是指针,因此即使我直接返回值,返回NULL也可以,但返回指向该值的指针似乎更为一般。否则,如果有人试图在那里存储一个实际为0的int,那么数据结构会声称它不在那里

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

最后,让一个只返回值的私有成员函数和一个只获取值地址的内联公共成员函数怎么样。这样,当find()函数的整个函数体都没有内联时,地址/取消引用操作至少会同时进行,并有更好的机会进行优化

私人: V_查找(键){ …//几十行。。。 } 公众: 内联V*查找(键){ 返回和查找(键); }
std::cout我已经看到了这两种情况。这实际上取决于编译器和级别优化。即使是内联的,我也见过编译器不会优化它的情况

要想知道它是否得到了优化,唯一的办法就是实际查看拆卸


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

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

要想知道它是否得到了优化,唯一的办法就是实际查看拆卸


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

\u find
返回类型为
V
的临时对象<代码>查找然后尝试获取临时文件的地址并将其返回。临时对象不会持续很长时间,因此得名。因此,
\u find
返回的临时文件在获得其地址后将被销毁。因此,
find
将返回指向先前已销毁对象的指针,该对象不正确。

\u find
返回类型为
V
的临时对象<代码>查找然后尝试获取临时文件的地址并将其返回。临时对象不会持续很长时间,因此得名。因此,
\u find
返回的临时文件在获得其地址后将被销毁。因此,
find
将返回一个指针,指向以前被破坏的对象,这是错误的。

您的代码(即使在第二次出现时)已被破坏
\u find
返回一个
V
,该
find
在返回其地址之前立即销毁

如果
\u find
V&
返回给一个比调用寿命长的对象(从而生成一个正确的程序),那么取消引用将是不可操作的,因为引用与机器代码级别的指针没有什么不同。

您的代码(即使是在第二个版本中)被破坏
\u find
返回一个
V
,该
find
在返回其地址之前立即销毁


如果
\u find
返回了一个
V&
到一个超过调用时间的对象(从而产生一个正确的程序),那么取消引用将是一个不可操作的,因为引用与机器代码级别的指针没有什么不同。

请注意,“只撤销彼此影响的操作”是一个非常小的集合,例如,它不适用于
&*p
,也不适用于
x+n-n
等等……find从不返回NULL。如果找不到元素,它只返回结束的迭代器。NULL和iterator::end()不相等。我知道它们不相等,这就是我说的原因(没有微不足道的.end()等价物)。我在这里使用NULL作为我的特殊值,以表示找不到它。在我的例子中,实现.end()实际上没有意义,因为迭代没有方向性。你不能使用引用而不是指针吗?那么,为什么不让
find
传递一个引用呢?它需要传递指针吗?请注意,“仅撤消彼此影响的操作”是一个非常小的集合,例如它不适用于
&*p
,也不适用于
x+n-n
,等等…find从不返回NULL。如果找不到元素,它只返回结束的迭代器。NULL和iterator::end()不相等。我知道它们不相等,这就是我说的原因(没有微不足道的.end()等价物)。我在这里使用NULL作为我的特殊值,以表示找不到它。在我的例子中,实现.end()实际上没有意义,因为迭代没有方向性。你不能使用引用而不是指针吗?那么,为什么不让
find
传递一个引用呢?它需要传递指针吗?抱歉,修复了代码。只是一个简单的错误,这篇文章也解释了我要做的事情。@Doug Treadwell:V是引用类型吗?否则,您将返回一个指向临时地址的指针。@DougTreadwell,您仍然使用临时地址 private: V _find(key) { ... // a few dozen lines... } public: inline V* find(key) { return &_find(key); } std::cout << *find(a_key);

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);

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


public:
inline V* find(key) {
    return &_find(key);
}

std::cout << *find(a_key);