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
[expr.add]/6 unfortunate example in Note #3614
Comments
It was intentional to talk about "pointer to base class" here, because you can get that via implicit conversions. I think the "array of one element" model doesn't go well with the broad restrictions in [expr.add]. I think we need a fix to the normative wording here. |
Editorial meeting: Return to CWG, normatively covered by p4.2. The added paragraph quoted above should be a note instead. |
Entire [expr.add]/6 should be a note? This doesn't sound right. |
@languagelawyer , the idea is that if P or Q point to a base class, they can't point to an array element (even if the addresses are the same), so the precondition in p4.2 is not satisfied and we fall through to "undefined behavior". |
@jensmaurer I see the idea. But we still need normative [expr.add]/6. float farr[2];
reinterpret_cast<double*>(&farr[0]) + 1; currently, there is UB in the second line because of [expr.add]/6. Without [expr.add]/6, the result of the full expression in the second line would be "pointer to |
Why are |
Did you mean that, since the I think change [basic.compound#3.sentence-12] to that
Which might fix this issue. |
This issue is not about which objects are considered to be array elements. |
Yes, I see your master argument in this issue. However, this issue actually introduces "This means that expressions bp + 0, bp + 1 were/are fine (before and after the resolution of the issue). ", which should also be fixed. struct B{
char b;
};
struct D: B{
char d;
};
D d[3];
B* bp = reinterpret_cast<B*>(&d[0]); // D*->void* still points to the element, void* -> B* not pointer-interconvertible Maybe this example could be accompanied with [expr.add]/6 |
[expr.add]/6 says:
The paragraph was added in the resolution of CWG1504 (the normative text has been a lil bit changed by CWG1865). Description of the issue says:
I suspect this meant something like
At C++11 times (when the issue was reported), [conv.ptr]/3 was saying that
bp
would be «pointer to the base class subobject of the derived class object». In C++17, [conv.ptr]/3 says the same thing.C++11 [expr.add]/4 was saying that «…a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one…». We may claim that currently the Standard says mostly the same thing.
This means that expressions
bp + 0
,bp + 1
were/are fine (before and after the resolution of the issue).bp + 2
was/is UB, but not because of the paragraph added by the resolution of the issue.So, the resolution of the issue changed nothing for the code above (if something like the code above was meant by the issue description). That's why I call the example in the Note unfortunate.
It is possible to construct an example with base and derived classes which would match [expr.add]/6 Note, however, this would be quite non-trivial, involving multiple or virtual inheritance, to make it possible to obtain a pointer of type "pointer to base" pointing to the derived class object, not the base class subobject.
I would suggest to change the Note to say, for example:
The text was updated successfully, but these errors were encountered: