Разрешена ли арифметика указателей на выделенном хранилище начиная с C ++ 20?


10

В стандарте C ++ 20 говорится, что типы массивов являются неявными типами времени жизни .

Означает ли это, что массив неявного типа времени жизни может быть создан неявно? Неявное создание такого массива не будет вызывать создание элементов массива?

Рассмотрим этот случай:

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");

Разве этот код больше не UB, так как C ++ 20?


Может быть, так лучше?

//implicit creation of an array of std::string 
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to the array of 10 std::string" 
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");

1
Я только что провел поиск по (черновому) стандарту C ++ 20 и не нашел ничего, что описывает массивы как «неявный тип времени жизни» (и, да, я искал варианты). Пожалуйста, предоставьте более подробное описание вашей претензии (например, раздел и пункт в стандарте). Немного трудно ответить на ваш вопрос, не имея возможности найти источник, не говоря уже о каком-либо соответствующем контексте.
Петр

1
@Peter: eel.is/c++draft/basic.types#9 , последнее предложение
Геза

Я просматривал PDF open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf (якобы последний рабочий проект), и в нем даже нет этого предложения. Похоже, вам также нужно найти значение «неявного времени жизни». Я подозреваю, что ваша ссылка, возможно, подняла некоторые "изменения в процессе", которые даже не превратились в выпущенные рабочие проекты.
Петр

1
@Peter Изменения являются результатом слияния P0593 в стандарт с недавней встречи в Праге. Они еще не выпустили получившийся черновик, но вы можете увидеть объединенную формулировку в этом коммите .
грецкий орех

Ответы:


3

Означает ли это, что массив неявного типа времени жизни может быть создан неявно?

Да.

Неявное создание такого массива не будет вызывать создание элементов массива?

Да.

Это то, что делает std::vectorреализуемым в обычном C ++.


Не могли бы вы также подтвердить, что std::launder(static_cast<std::string*>(ptr))не возвращает указатель на первый элемент массива, потому что он не в пределах своего времени жизни, но что std::launder(static_cast<std::string(*)[10]>(ptr))возвращает указатель на массив, потому что массив находится в пределах его времени жизни?
Олив

Это кажется правильным для меня.
ТК

@Oliv И я полагаю, что в std::launderдействительности это не нужно, потому что eel.is/c++draft/intro.object#11 гарантирует, что ptrон уже будет указывать на массив?
грецкий орех

@walnut, я пропустил это. Таким образом, static_castчтобы std::string (*) [10]должно быть достаточно! ТХ.
Олив

@Oliv Но я думаю, что вопрос в том, будет ли ваш первый пример без него std::launderхорошо определен. Нет std::stringобъекта для указания, но он ptrможет указывать на массив, так что статическое приведение оставит значение без изменений и также sptrбудет указывать на массив. С std::launderUB это просто из-за std::launderтребований России.
грецкий орех
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.