在C ++中,如果返回指针并立即取消引用,那两个操作是否会被优化掉?

时间:2011-09-24 06:46:28

标签: c++ pointers compiler-construction compiler-optimization

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

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

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

但是,我想知道这里的效率是否有任何损失,因为编译器应该优化掉那些只能消除彼此影响的行为。问题是两者被函数返回分开,所以可能无法检测到它们只是相互撤消。

最后,如果有一个私有成员函数只返回值,那么内联公共成员函数只接受值的地址。然后至少地址/解除引用操作将一起发生并且更有可能被优化,而find()函数的整个主体没有内联。

<击>

<击>
private:
V _find(key) {
   ... // a few dozen lines...
}


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

std::cout << *find(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);

3 个答案:

答案 0 :(得分:2)

_find返回V类型的临时对象。 find然后尝试获取临时地址并将其返回。临时对象不会持续很长时间,因此得名。因此_find返回的临时值将在获取其地址后被销毁。因此find将返回一个指向先前被破坏的对象的指针,这是不好的。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

你的代码(即使是第二个版本)也被破坏了。 _find会返回Vfind会在返回地址之前立即销毁。

如果_find将一个V&返回给一个比调用更长的对象(从而生成一个正确的程序),那么取消引用将是一个无操作,因为引用与指针没有区别在机器代码级别。