можешь понять что оно делает? )
я не утверждаю, что это бесполезно мне интересна мотивация человека, который писал бумагу, и членов комитета, которые её приняли
Зайдите с другой стороны: какой интерфейс сделали бы вы? Я не считаю std::align удобным, но однозначно лучший вариант я затрудняюсь предложить.
std::pair<void *, size_t> align(size_t alignment, size_t obj_size, void * ptr, size_t mem_size); или вообще void * align(size_t alignment, size_t obj_size, void * ptr, size_t mem_size);
Что будет возвращено в обоих случаях если не хватило места?
nullptr или nullptr, 0
Тогда код для работы будет выглядеть примерно так: 1) auto [p, s] = std::align(alignment, size, ptr, mem_size); if (p) { ptr = p; mem_size = s; return p; } else { // handle error } 2) auto p = std::align(alignment, size, ptr, mem_size); if (p) { ptr = p; mem_size = (char*)p + size; return p; } else { // handle error } На мой взгляд такой код выглядит хуже чем с существующим интерфейсом.
вместо pair лучше возвращать условную struct align_result_t с двумя полями
не согласен если вам так хочется изменять аргументы std::tie(ptr, mem_size) = std::align(alignment, size, ptr, mem_size); if (ptr) { ... } else { /* handle error */ }
тогда std::tie нельзя будет использовать
а зачем его использовать?
сообщение выше с примером
Это не эквивалентный код. Изменен порядок проверки результата и обновление ptr. В этом коде ptr обнуляется при нехватке памяти.
Я веду к тому, что в текущем интерфейсе состояние представлено парой ptr и mem_size. В то время как возвращаемое значение указывает на успех операции. Это разные значения.
Я не могу представить ситуацию, когда вам в "успешной" ветке не нужен старый указатель, а в "провальной" нужен.
Зачем указывать на успех операции, возвращая тот же указатель второй раз? Почему бы не вернуть true/false?
Да, можно было бы и так, но и вреда от возврата указателя я не вижу.
А что такое старый указатель? На сколько я вижу, идея этого интерфейса примерно в таком: template <class T> T* allocate_on_arena() { static std::array<char, 4096> s_arena; static char* s_ptr = s_arena.data(); static size_t s_size = s_arena.size(); if (void* p = std::allocate(alignof(T), sizeof(T), s_ptr, s_size)) { return new(p) T; } else { // if allocation failed, state haven't changed, so it should be possible to try to allocate smaller type T return nullptr; } } Для выравнивания одного объекта интерфейс std::align не слишком удобен, с этим я не буду спорить. Но как выглядит ваш юзкейс?
Таки я не прав. Эти два указателя отличаются на sizeof(T), поэтому нет, bool'а не достаточно.
у вас allocate вместо align, это ошибка или специально так? на первый взгляд для юзкейса, который вы привели, больше подойдет просто использовать std::aligned_storage вместо std::array мой юзкейс простой: есть один объект header, и некоторое, определяемое в рантайме, количество объектов entry их все хочется разместить в памяти за одну аллокацию
нет, они одинаковые
Это простейшая арна. std::aligned_storage здесь ничем не поможет, потому что на арене могут лежать любые T вперемешку. Ошибка там только в том что не обратываются исключения выброшенные из конструтора, но и инвариант функции это не ломает. upd: Да, я допустил несколько ошибок в том числе написал std::allocate вместо std::align.
я не очень понимаю, как на ней может быть больше одного объекта, если s_ptr не сдвигается кроме как на alignment
гм. Действительно. Беру свои слова назад: теперь и для меня этот интерфейс выглядит довольно странно. С другой стороны поведение, которого ожидал я как раз мешает обработке исключения в конструкторе.
Обсуждают сегодня