Code:
#include <cstdio>
#include <new>
struct Foo {
char ch;
~Foo() { ++ch; }
};
int main() {
static_assert(sizeof(Foo) == 1);
char buffer;
auto const* pc = new (&buffer) Foo{42};
// Change value using only the const pointer
std::printf("%d\n", +buffer);
pc->~Foo();
std::printf("%d\n", +buffer);
}
I am not causing any UB as far as I can tell, but GCC and Clang disagree on the result. I think the output should obviously be "42 43". That is the case for Clang, but GCC thinks the output is "42 0". How is that possible? Who zeros out the buffer? Am I missing something?
In your final line, the lvalue buffer
doesn't access any object.
The char
object that was there initially had its lifetime ended by reusing its storage for a Foo
. The Foo
had its lifetime ended by invoking the destructor. And no one created any object in the storage after that.
lvalue-to-rvalue conversion (which is what +buffer
does, but passing buffer
as an argument to a variadic function would too) is not permitted where no object exists.