Reputation: 1035
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
Upvotes: 4
Views: 1172
Reputation: 117168
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*
.
Upvotes: 2
Reputation: 10261
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.
Upvotes: 0