2

AFAIK 获取右值的地址是非法的,因为地址运算符&获取一个左值并返回对象调用地址的地址。

这是一个我试图理解但发现它有点混乱的例子:

#include <deque>
#include <iostream>

int main() {
    using std::cout;
    using std::endl;

    std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 };

    std::deque<int>::iterator it = di.end() - 1; 

    cout << *it << endl;
    cout << &it-- << endl; // is it UB?
    cout << *it << endl;
    cout << &it-- << endl;
    cout << *it << endl;
    cout << &it-- << endl;
    cout << *it << endl << endl;

    cout << &--it << endl; // ok
    cout << *it << endl; // ok
    cout << &--it << endl; // ok
    cout << *it << endl; // ok



    std::cout << std::endl << "done!" << std::endl;
}
  • 在我使用预减运算符的行中,它是可以的,因为该运算符&具有相同的优先级,并且从右到左(RL)进行评估,因此--首先评估并返回一个左值(也采用左值) . then&被评估,所以&左值是可以的。

  • 上述后减运算符中的问题,它接受一个左值并返回一个右值,并且优先级高于&. 因此,在这些表达式中,我调用&了通常不允许的右值。但是为什么代码编译并给出不同的结果(地址)?

  • 在带有标志的 Wandbox 上编译时,-pedantic它不会编译:

    prog.cc:25:17: error: taking address of rvalue [-fpermissive]
       25 |  cout << &offEnd-- << endl; // -- has higher precedence than & thus this expression decrements offEnd and returns a copy of original of offEnd then print the address of this original object (before decrementing it)
    

    也在 MSVC++14 上使用/Wall.

  • 那么它是我的代码中未定义的行为吗?

  • 那么为什么 C++ 允许&在右值上调用运算符的地址而标准不允许呢?
  • 最后我想知道这些不同的地址在这样的表达中来自哪里:std::cout << &it-- << std::endl;?但是取消引用的值是正确的!
4

0 回答 0