Why calling address-of operator on rvalues compiles?

404 views Asked by At

AFAIK it is illegal to take the address of an rvalue because the address-of operator & takes an lvalue and returns the address of the object's called on address.

Here is an example I've tried to understand but find it a bit confusing:

#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;
}
  • In the lines where I've used the pre-decrement operator it is OK because this operator and & have the same precedence level and are evaluated from right-to-left (RL) thus -- evaluates first and it returns an lvalue (takes also lvalue). then & is evaluated so & on an lvalue is OK.

  • The problem above in the post-decrement operator which takes an lvalue and returns an rvalue and has higher precedence over &. So in these expressions I am calling & on rvalue which is normally not allowed. But why the code compile and gives different results (addresses)??

  • When compiled on Wandbox with flag -pedantic it doesn't compile:

    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)
    

    Also on MSVC++14 with /Wall.

  • So is it undefined behavior in my code?

  • so why C++ allowed calling address of operator & on rvalue while the standard disallows it?
  • Finally I want to know where theses different addresses come from in such expression: std::cout << &it-- << std::endl;? But the values of de-referencing are correct!
0

There are 0 answers