简体   繁体   中英

Lvalue and Rvalue with C++ arrays

I have done some experimentation on array and learning about L-value and R-values,

From my understanding:

L-values are object that has an identifiable memory location, R-values are defined by exclusion, anything that is not a L-value, is a R-value, by exclusion.

Here is my experiment:

int array [] = {8, 7, 6, 5, 4};            
std::cout << array << std::endl;           //0x61fedc
std::cout << &array << std::endl;          //0x61fedc
std::cout << *(&array) << std::endl;       //0x61fedc
std::cout << *array << std::endl;          //8

Line 1 and 2 should come with no surprises, when you evaluate an array, it will return the address of the first element

What is confusing is the results from line 3. *(&array) is saying to me "what is the de-referenced value of the first memory address of the variable array , I was expecting 8 , however i got back the first memory address, why is that?

Lastly, line 4 evaluates to 8 , which was expected. However, since the dereferencing operator works on the array variable, why can't we conclude that array is a pointer (points to the first element memory address)? I know this can't be truth but they behaves the same?

Thank you

I find an example clarifying. Here I have some foo overloads accepting the versions you've used in your code.

#include <iostream>
#include <string>

template<size_t N>
std::string foo(const int(&)[N]) {
    return std::string(" int(&)[") + std::to_string(N) + "]\n";
}

template<size_t N>
std::string foo(const int(*)[N]) {
    return std::string(" int(*)[") + std::to_string(N) + "]\n";
}

std::string foo(const int*) {
    return " int*\n";
}

std::string foo(int) {
    return " int\n";
}

int main() {
    int array [] = {8, 7, 6, 5, 4};
    std::cout << array     << foo(array);
    std::cout << &array    << foo(&array);
    std::cout << *(&array) << foo(*(&array));
    std::cout << *array    << foo(*array);
}

Possible output:

0x7ffeaf43a610 int(&)[5]
0x7ffeaf43a610 int(*)[5]
0x7ffeaf43a610 int(&)[5]
8 int

As you can see, with this combination of overloads, none of the versions decay into an int* .

Your question already has an answer here . Basically, sometimes an array to pointer conversion takes place, sometimes it doesn't.

Your definition of an lvalue is incorrect. An lvalue must be capable of being assigned to; it is valid on the left hand side of assignment. A read-only location has an address, for example, but is not an lvalue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM