-
Notifications
You must be signed in to change notification settings - Fork 771
Example in [allocator.requirements.general] incorrectly uses launder? #4553
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
Comments
The usage is indeed incorrect. The valid cast is |
Incidentally, the standard never specifies which implicitly created objects whose addresses are the address of the start of the region of storage. |
That's intentional. The right one is selected, by magic, if that would make the program correct. None of this is editorial. |
So, we cannot plainly determine whether a program is well-formed. For instance struct X{
int x;
};
auto ptr = (X*)malloc(sizeof(X));
ptr->x = 0;// is well-formed? No one can say the return value of |
No, that's not what the wording means. There is no "implementor of the function |
«well-formed» should not be confused with «well-defined» |
Yes, and |
@jwakely However, the standard/implementation never says that the object of type
we can say the object of type |
Cite the quotes of the definition of
struct T{
int i;
char c;
};
auto tptr = (T*)malloc(sizeof(T));
tptr-> a = 0;
auto iptr = (int*)malloc(sizeof(T));
*iptr = 0; The standard only specifies that an object of type |
P2590R0 addressed this issue by replace the use with |
Yes, because that's a situation where we're not intending to re-use the existing bytes for the to-be object representation. As-is, the optimizer can apply dead-store elimination for any store to the affected region. |
|
That core issue far predates |
The goal of CWG1997, in the first place, should be to clarify that the lifetime of objects created by new-expression using non-allocating |
Although std::launder should not be required at all and everything should correct itself.
Example for (1). If the object is created implicitly, then placement new shall return a pointer to it. Therefore this is a perfectly valid code point to the first element of the array.
|
@MX20 |
Right , but what does it change? For non implicitly created types it may be the pointer to the first element before its lifetime started which can be used in limited ways - just enough to create an object in it using another placement new |
That |
I see , fair enough |
I think there's an interesting decision for CWG to make here. I agree with the issue description:
I think we can resolve the disagreement between the claim about a valid use of
Option 2 is probably the simplest if it works. |
int arr[1];
for (int i = 0; i < INT_MAX; i++) ::new (&arr[0]) int {};
std::launder(&arr[0]); // which of INT_MAX+1 objects std::launder returns pointer to? |
The rule for transparently replacing makes all of these pointer values equivalent, IIUC. |
From https://stackoverflow.com/q/66755218
[tab:cpp17.allocator] has the following example added by p0593r6:
If
T
is not an implicit-lifetime type, then, even if an object of typeT[m ≤ n]
is created, the lifetimes of the array elements are not started, which meanslaunder
's preconditions are violated:The text was updated successfully, but these errors were encountered: