Date: Thu, 17 Aug 2023 19:01:45 +0100
On Thursday, August 17, 2023, Tom Honermann wrote:
> The code has undefined behavior since
> no object of std::array<T,len> actually
> exists at the address returned by
> pretend_is_std_array().
Yeah but something ABI-compatible with it does. But even if it were
zero-initialised memory, that can be an array of int's all set to zero.
> While the code might exhibit the behavior you
> want today, there is no guarantee that a future
> compiler upgrade won't include optimizer
> changes that cause it to behave differently.
> Violating the C++ object model is not
> something I would recommend.
Change the pointer to 'a pointer to volatile' and then use std::launder on
it.
By the way I've only ever seen one example of C++ code that behaves
differently when you use 'launder', and it involved a constructor using
'placement new' to invoke a constructor belonging to another class on the
current object, something like:
MyClass::MyClass(void)
{
::new(this) SomeOtherClass();
}
The use of 'launder' prevented caching of the vtable -- which can also be
achieved by making the object 'volatile' like I did in a puzzle I composed
on Codewars:
https://www.codewars.com/kata/6359c81e00fba2852618a1cb/
The object model in C++ isn't as wild and wacky as some people make it out
to be. There isn't and optimiser up on a lighthouse with a sniper rifle
waiting for the perfect opportunity to invoke UB.
> The code has undefined behavior since
> no object of std::array<T,len> actually
> exists at the address returned by
> pretend_is_std_array().
Yeah but something ABI-compatible with it does. But even if it were
zero-initialised memory, that can be an array of int's all set to zero.
> While the code might exhibit the behavior you
> want today, there is no guarantee that a future
> compiler upgrade won't include optimizer
> changes that cause it to behave differently.
> Violating the C++ object model is not
> something I would recommend.
Change the pointer to 'a pointer to volatile' and then use std::launder on
it.
By the way I've only ever seen one example of C++ code that behaves
differently when you use 'launder', and it involved a constructor using
'placement new' to invoke a constructor belonging to another class on the
current object, something like:
MyClass::MyClass(void)
{
::new(this) SomeOtherClass();
}
The use of 'launder' prevented caching of the vtable -- which can also be
achieved by making the object 'volatile' like I did in a puzzle I composed
on Codewars:
https://www.codewars.com/kata/6359c81e00fba2852618a1cb/
The object model in C++ isn't as wild and wacky as some people make it out
to be. There isn't and optimiser up on a lighthouse with a sniper rifle
waiting for the perfect opportunity to invoke UB.
Received on 2023-08-17 18:01:48