Namespaces
Variants
Views
Actions

Talk:cpp/string/byte/memset

From cppreference.com

The use of memset inside a constructor is dangerous even if the class itself is trivially copyable but if that class is not final and can be inherited because it could overwrite the most derived class's other virtual base (subobject).


Here is an example (which is initially shown https://bugs.llvm.org/show_bug.cgi?id=40245 and https://stackoverflow.com/questions/54102890/class-using-virtual-inheritance-seems-to-allow-a-base-class-constructor-to-overw),

struct A {
    A() { memset(this, 0, sizeof(A)); } // this will overwrite B.b when C constructs.
 
    int i;
    char a;
};
 
struct B { char b = 'b'; };
struct C : virtual B, A {};
 
char foo() {
    C c;
    return c.b;
}
The standard states that all base class subobjects are potentially overlapping, not only empty ones.
The behavior above is likely required by Itanium ABI on which whether base types are all POD-types (in ancient C++) affects whether corresponding base class subobjects overlap.
However, I don't know whether the behavior is undefined. --Fruderica (talk)

[edit] Shall we use TrivialType instead of TriviallyCopyable?

I think that a TriviallyCopyable type which is not a TrivialType may not accept all possible bit patterns, and memset may turn an object of such type into an invalid state. --Fruderica (talk) 03:45, 15 March 2019 (PDT)

If TriviallyCopyable is not the right constraint, then neither is TrivialType. For example, bool is a TrivialType, but memset(&bool_variable, 42, 1); is likely to give bool_variable an invalid bit pattern. --D41D8CD98F (talk) 04:04, 15 March 2019 (PDT)