Является ли четко определенным / законным многократное размещение new по одному и тому же адресу?

(Примечание: этот вопрос был мотивирован попыткой придумать хакерский метод препроцессора для генерации бездействующего выделения чтобы ответить на этот другой вопрос:

Макрос, принимающий новый объект

... так что имейте это в виду!)

Вот надуманный класс:

class foo {
private:
    int bar;
public:
    foo(int bar) : bar (bar)
        { std::cout << "construct foo #" << bar << std::endl; }
    ~foo()
        { std::cout << "destruct foo #" << bar << std::endl; }
};

... который я распределю следующим образом:

// Note: for alignment, don't use char* buffer with new char[sizeof(foo)] !
void* buffer = operator new(sizeof(foo));

foo* p1 = new (buffer) foo(1);
foo* p2 = new (buffer) foo(2);

/* p1->~foo(); */ /* not necessary per spec and problematic in gen. case */
p2->~foo();

На gcc, который у меня есть, я получаю «ожидаемый» результат:

construct foo #1
construct foo #2
destruct foo #2

Что здорово, но может ли компилятор / среда выполнения отклонить это как злоупотребление и при этом остаться на правильной стороне спецификации?

Как насчет многопоточности? Если нас на самом деле не заботит содержимое этого класса (скажем, это просто фиктивный объект), не произойдет ли сбой, по крайней мере, как в еще более простом приложении, которое мотивировало это с помощью POD int?

13
задан Community 23 May 2017 в 12:22
поделиться