New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[basic.lval] Remove an incorrect statement that assignment expects PR-value right operands #4875
Conversation
This proposed change is incorrect. Assignment does expect a prvalue as the right operand, and the lvalue-to-rvalue conversion [conv.lval] is applied if it isn't. (That conversion actually reads the value designated by the lvalue, which is obviously necessary to actually perform the assignment.) |
@jensmaurer Based on Christoper Strachey’s papers, I thought that what makes an expression an L-value expression is that it has two values (so there are two possible evaluation modes): a value representing its content (called an R-value) and a value representing its storage location (called an L-value). And that what makes an expression an R-value expression is that it has a single value: a value representing its content (R-value). And that the assignment command Thus what the C++ standard calls ‘lvalue-to-rvalue conversion’ seems to be R-value evaluation mode. We are not really converting the value category of an expression, we are evaluating an expression in a particular mode. So I find the C++ terminology ‘lvalue-to-rvalue conversion’ a little confusing here. |
Strachey's model may be isomorphic with the one in the C++ standard, but obviously the C++ standard uses its own model. You can think in terms of Strachey's model if it helps you, but the standard doesn't use it. And you definitely can't change bits of the C++ standard to inconsistently use that model in just one place. |
Yes, when I proposed this change I was not aware of this lvalue-to-rvalue conversion terminology and thought it was a mistake. Sorry for the noise. |
I'm not even sure that alternative model is quite right. You can have glvalues of incomplete type, but you cannot convert those to prvalues. So I don't find it helpful to think of "two values at once", but I think the standard's approach of allowing conversion of one to the other is more appropriate. |
Strachey wasn't even talking about C (maybe Pascal?) so it's unsurprising if it doesn't work for C++, invented years after his death. |
That is true, we get a compiler warning when trying to use a glvalue denoting an automatic object of incomplete type: #include <iostream>
int main() {
int i; // creates an automatic object of incomplete type
std::cout << &i; // okay: prints the lvalue of i
std::cout << i; // warning: prints the indeterminate rvalue of i
return 0;
} I am not sure if Strachey wrote about this, but I think he did when developing his denotational semantics.
In his influential paper ‘Fundamental Concepts in Programming Languages’, Strachey was actually talking about CPL, an early ancestor of the C language via the BCPL and B languages. |
No it doesn't, This is what tkoeppe was talking about:
But this also belongs on Stack Overflow, not here. |
My bad, I mixed up incomplete type with indeterminate value, though in both cases glvalue expressions cannot be converted to prvalue expressions. |
This is a perfectly valid assignment with an L-value right operand: