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
[conv.lval] Determine the value of a constant without accessing an object #4495
base: main
Are you sure you want to change the base?
Conversation
source/expressions.tex
Outdated
\item Otherwise, if $E$ is a constant expression that designates an object | ||
that is usable in constant expressions ([expr.const]), | ||
the result is the value of that object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems much broader than the rule in /2.2. This would also remove the access in:
struct X { int a; };
constexpr X x = {1};
int n = (&x)->a;
... which currently does result in an odr-use of x
and an access. Changing that doesn't seem editorial.
Can we make the words here more directly refer back to the /2.2 case somehow? Maybe something like:
\item Otherwise, if $E$ is potentially evaluated and the object designated by $E$ is not accessed, as specified above, the designated object is necessarily usable in constant expressions ([expr.const]) and the result is the value of that object.
(I don't like "is necessarily" here. Do we have another way to say "must be" without making ISO angry?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe we could inline /2 into these bullets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also has interactions with the very definition of "lvalue":
struct S
{
static const int a = 1;
};
int main()
{
return S::a; // no odr-use; no definition of S::a needed
}
[intro.object] p1 "An object is created by a definition (6.2) ..."
[basic.lval] p1 "A glvalue is an expression whose evaluation determines the identity of an object or function.
How can you identify an object that wasn't ever created (because there is no definition)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it works best to integrate p2 into the "result" bullets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe say the result is the value of \tcode{x}'s initializer.
in non-odr-used variable case? Variable is not an object, it doesn't have value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW
struct S
{
int m;
};
int main()
{
&S::m;
}
[expr.prim.id.qual] says that a qualified-id denoting data member is an lvalue, but I don't think S::m
in &S::m
can denote an object. Even though we have pointer-to-member, IIUC S::m
is still an lvalue there, which makes me feel uncomfortable. Should this be a Core issue? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe say the result is the value of \tcode{x}'s initializer. A variable that is usable in constant expressions does not always have an initializer
A variable or temporary object o is constant-initialized if.
- either it has an initializer or its default-initialization results in some initialization being performed
struct A{
int v = 1;
};
Editorial meeting 2021-04-16: "const int x = 10000; sizeof(char{x})" needs the value of x, but is not potentially evaluated. Fix by moving the "set of potential results" wording to the front. Then, create a diff so that CWG can sign off. Also add the example. |
Fixes #4493