Size: a a a

2020 June 22

m

magras in pro.cxx
Ну в С++17 правильный путь это placement new. В новом тоже.
В прочем я не уверен, что такой же код с обычным int'ом вместо указателя, был бы переносимым.
источник

AT

Andrew Titov in pro.cxx
Vlad Serebrennikov
он так-то знает, время жизни какого объекта в том куске памяти начинается. и еще стандарт говорит, что время жизни подобъектов, которые принадлежат к implicit-lifetime типам, начинается вместе с самим объектом. (указатели к этим типам относятся)
> время жизни объекта в куске памяти
А тип объекта ему известен? Мне кажется, что нет.
источник

S

Serg in pro.cxx
если placement new, то зачем calloc()?, и malloc() достаточно
calloc становится почти бесполезным
источник

VS

Vlad Serebrennikov in pro.cxx
Andrew Titov
> время жизни объекта в куске памяти
А тип объекта ему известен? Мне кажется, что нет.
как у такого объекта потом вызвать нужный деструктор в таком случае
источник

A

Alex in pro.cxx
magras
struct S {
 void* p;
};

S* s = reinterpret_cast<S*>(calloc(sizeof(int))); // note this memory guaranteed to be filled with zeros
assert(s->p == nullptr);

Такой код был UB. В 20ом стандарте UB нет, но срабатывание assert'а зависит от битового представления nullptr.
Почему не UB, что поменялось? Разве алиасинг разрешили?
источник

m

magras in pro.cxx
источник

ПК

Побитый Кирпич... in pro.cxx
magras
struct S {
 void* p;
};

S* s = reinterpret_cast<S*>(calloc(sizeof(int))); // note this memory guaranteed to be filled with zeros
assert(s->p == nullptr);

Такой код был UB. В 20ом стандарте UB нет, но срабатывание assert'а зависит от битового представления nullptr.
Ну то есть сломался невалидный код, не страшно :)
источник

A

Alex in pro.cxx
спасибо. То есть это не UB именно с функциями, которые порождают новую память?
источник

ПК

Побитый Кирпич... in pro.cxx
(при том сломался на экзотической архитектуре)
источник

AT

Andrew Titov in pro.cxx
Vlad Serebrennikov
как у такого объекта потом вызвать нужный деструктор в таком случае
Как я понял, в этом случае деструктор должен быть тривиален.
источник

S

Serg in pro.cxx
Vlad Serebrennikov
как у такого объекта потом вызвать нужный деструктор в таком случае
p->~T()
источник

VS

Vlad Serebrennikov in pro.cxx
Andrew Titov
Как я понял, в этом случае деструктор должен быть тривиален.
Scalar types, implicit-lifetime class types ([class.prop]), array types, and cv-qualified versions of these types are collectively called implicit-lifetime types.

A class S is an implicit-lifetime class if it is an aggregate or has at least one trivial eligible constructor and a trivial, non-deleted destructor.
источник

VS

Vlad Serebrennikov in pro.cxx
коротко: да
источник

ПК

Побитый Кирпич... in pro.cxx
Alex
Почему не UB, что поменялось? Разве алиасинг разрешили?
Там нет юрисдикции алиасинга, потому что функции типа malloc якобы под капотом создают объект нужного типа, а тогда алиасинга никакого нет
источник

VS

Vlad Serebrennikov in pro.cxx
Andrew Titov
Как я понял, в этом случае деструктор должен быть тривиален.
но это не отменяет того факта, что тип компилятору известен
источник

A

Alex in pro.cxx
Побитый Кирпич
Там нет юрисдикции алиасинга, потому что функции типа malloc якобы под капотом создают объект нужного типа, а тогда алиасинга никакого нет
Понял, спасибо. Давно ещё смотрел на этот PR, но потом потерял его из виду. Полезное и нужное нововведение.
источник

AT

Andrew Titov in pro.cxx
Vlad Serebrennikov
но это не отменяет того факта, что тип компилятору известен
Но и не подтверждает его, так?
источник

VS

Vlad Serebrennikov in pro.cxx
Andrew Titov
Но и не подтверждает его, так?
An object has a type
источник

VS

Vlad Serebrennikov in pro.cxx
вот и подтверждение
источник

m

magras in pro.cxx
Serg
если placement new, то зачем calloc()?, и malloc() достаточно
calloc становится почти бесполезным
Наверное, достаточно написать static_assert((uintptr_t)nullptr == 0); и тогда можно инициализировать указатели битовым нулем. То есть мне кажется, перевели из UB в implementation defined.
источник