C++ Logo

std-discussion

Advanced search

implicit lifetime and copy constructors

From: Federico Kircheis <federico_at_[hidden]>
Date: Fri, 24 Nov 2023 10:24:45 +0100
Hello, I have a question regarding implicit lifetimes and
copy-constructors, maybe someone can help me.


Consider following example

----
struct buff_int{
 unsigned char buffer[sizeof(int)];
 buff_int(int i){
  std::memcpy(buffer, &i, sizeof(int));
 }
 int get_int() const {
  int* j = std::launder(reinterpret_cast<int*>(buffer));
  return *j;
 }
};
auto val = buff_int(42);
int i = val.get_int();
----
As far as I can see, everything is well-defined.
std::memcpy creates implicitly an int object, and before accessing it, 
I'm using std::launder.
But what about
----
struct buff_int{
 /* as before */
};
auto val = buff_int(42);
int i = val.get_int();
auto val2 = val;
int i2 = val.get_int();
----
Is the line "int i2 = val.get_int();" well-defined?
AFAIK the copy constructor does not necessarily call std::memcpy, so it 
does not seem defined that the buffer in val2 has an int object with 
implicit lifetime contained in the buffer.
A similar question holds for the assignment operator.
As assignment does not necessarily use memcpy, it does not seem to end 
and/or begin an implicit lifetime, thus
----
struct buff_int{
 /* as before */
};
auto val = buff_int(42);
int i = val.get_int();
auto val2 = buff_int(-1);
val = val2;
int i2 = val.get_int();
----
also seems to be UB.
Thus to avoid UB/for having value semantic, the structure "buff_int" 
needs user-defined copy-constructor and assignment operator that uses 
memcpy internally, is that correct?

Received on 2023-11-24 09:24:51