Is circumventing a class' constructor legal or does it result in undefined behaviour?

后端 未结 7 499
甜味超标
甜味超标 2020-11-29 11:06

Consider following sample code:

class C
{
public:
    int* x;
};

void f()
{
    C* c = static_cast(malloc(sizeof(C)));
    c->x = nullptr; // &         


        
7条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-29 11:49

    For the most part, circumventing the constructor generally results in undefined behavior.

    There are some, arguably, corner cases for plain old data types, but you don't win anything avoiding them in the first place anyway, the constructor is trivial. Is the code as simple as presented?

    [basic.life]/1

    The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. [ Note: initialization by a trivial copy/move constructor is non-vacuous initialization. — end note ] The lifetime of an object of type T begins when:

    • storage with the proper alignment and size for type T is obtained, and
    • if the object has non-vacuous initialization, its initialization is complete.

    The lifetime of an object of type T ends when:

    • if T is a class type with a non-trivial destructor ([class.dtor]), the destructor call starts, or
    • the storage which the object occupies is reused or released.

    Aside from code being harder to read and reason about, you will either not win anything, or land up with undefined behavior. Just use the constructor, it is idiomatic C++.

提交回复
热议问题