LINUX.ORG.RU

make_unique vs new

 ,


0

3

Добрый день. Подскажите пожалуйста, в чем преимущество make_unique перед просто созданием unique_ptr. Как я понял одно из преимуществ это отсутствие утечек при make_unique и где-то еще слышал про проблемы фрагментации. Кто сталкивался с этими, можете пояснить пожалуйста?


Ответ на: комментарий от kvpfs

make_unique<T, …> требует чтобы конструктор T был public. А иногда хочется сделать private конструктор + фабричную функцию.

pr849
()
Последнее исправление: pr849 (всего исправлений: 1)
Ответ на: комментарий от kvpfs

Это лишь показывает, что массивы не надо копировать.

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

Но достаточно переписать так и никаких копий

Нет, это чушь: ты не можешь знать, где копирование было устранено, а где нет, не посмотрев дизассемблированный код – который ты смотреть не будешь, пока не появится необходимость.

Кстати, удачи получить «не ЮБ» при работе с нетривиально копируемыми типами.

Но у тебя ЮБ, а у меня - нет.

Но меня это не волнует, потому что это работает и будет работать. Если будет волновать – есть -fno-strict-aliasing, std::launder и другие способы решить проблему.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от kvpfs

Не, не аргумент, достаточно сделать один макрос:

  1. Создать проблему
  2. Начать ее решать
  3. Героически ее решить

Макрос твой – убогая мазня. Он ничем не лучше std::make_shared, более того – он использует вариадики вместо параметр паков, что автоматически делает его хуже.

Порожден он желанием решить побольше «проблем» вместо того, чтобы сделать что-нибудь полезное.

Ничего плохого в new или static_cast нет.

По таким мелочам легко определить хелоу ворлд первокурсника от серьёзной поделки.

https://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01034_source.html

Ctrl+F «_cast».

…ой. libstdc++ заносим в список «хелоу ворлдов первокурсика».

Siborgium ★★★★★
()
Ответ на: комментарий от LamerOk

Потому что страницы могут не читаться при полностью исправном ПК.

https://www.sublimetext.com/blog/articles/use-mmap-with-care

As it turns out, the ticket comes from someone using a networked drive. Their network happened to disconnect while your memory mapped file was open, and since the file no longer existed the OS couldn’t load it into ram for you and gave you a SIGBUS instead.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 2)
Ответ на: комментарий от Siborgium

для корректной обработки ошибок mmap’нутого файла нужно писать хэндлер SIGBUS

Ну ок. И как будет выглядеть __ корректная __ обработка ошибок mmap’нутого файла?

  1. Как ты отличишь SIGBUS при обращении к одному файлу от SIGBUS’а при обращении к другому?
  2. Как ты отличишь SIGBUS от заmmapленного файла от SIGBUS’а не связанного с mmapом файла?
  3. Почему ты не предлагаешь писать хэндлер для SIGSEGV?
LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Как ты отличишь SIGBUS при обращении к одному файлу от SIGBUS’а при обращении к другому?

Как ты отличишь SIGBUS от заmmapленного файла от SIGBUS’а не связанного с mmapом файла?

В общем случае – никак. В частных можно расставлять флаги при обращениях к файлу.

Почему ты не предлагаешь писать хэндлер для SIGSEGV?

Потому что SIGSEGV сигнализирует об ошибке в логике программы, тогда как SIGBUS – об ошибке чтения-записи.


Вот поэтому read и предпочтительнее в случаях, когда нужно уметь обработать подобную ошибку. mmap не панацея, у него свои проблемы.

Siborgium ★★★★★
()
Ответ на: комментарий от LamerOk

Как ты отличишь SIGBUS при обращении к одному файлу от SIGBUS’а при обращении к другому?

Как ты отличишь SIGBUS от заmmapленного файла от SIGBUS’а не связанного с mmapом файла?

В обработчик сигнала передаётся адрес ошибки обращения к пямяти. Можно найти к какому файлу он относится.

X512 ★★★★★
()
Ответ на: комментарий от Siborgium

Потому что SIGSEGV сигнализирует об ошибке в логике программы, тогда как SIGBUS – об ошибке чтения-записи.

Но это - очевидное 4.2. В документации английским по ASCII написано:

       SIGSEGV
              Attempted write into a region mapped as read-only.

       SIGBUS Attempted access to a page of the buffer that lies beyond
              the end of the mapped file.

То есть оба случая - ошибка в логике программы. И брошенное хрен-пойми-что-хрен-пойми-где из ссылке выше - это результат броска монетки конкретным разрабом конкретного драйвера файловой системы. На любой другой системе / драйвере может прилететь любой другой сигнал или вообще никакого сигнала.

В частных можно расставлять флаги

Можно и штаны через голову надевать, но зачем?

LamerOk ★★★★★
()
Ответ на: комментарий от X512

В обработчик сигнала передаётся адрес ошибки обращения к пямяти.

Адрес __ чего __? Потому что в 99% сигналах там передаётся (если вообще передаётся) адрес машинной инструкции, вызвавший сбой, а не адрес, по которому инструкция обращалась к данным:

       * SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP fill in si_addr
         with the address of the fault.  On some architectures, these
         signals also fill in the si_trapno field.

И конкретное поведение целиком зависит от платформы (OS + HW).

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Но это - очевидное 4.2. В документации английским по ASCII написано:

Нет, это не 4.2. Оба приведенных примера сводятся к тому, что операция выполняется над адресом, который не относится к допустимым для записи.

При этом, если внимательно прочитать английский по ASCII, можно увидеть волшебную

An implementation may generate SIGBUS signals when a reference would cause an error in the mapped object, such as out-of-space condition.

Siborgium ★★★★★
()
Ответ на: комментарий от LamerOk

Адрес __ чего __? Потому что в 99% сигналах там передаётся (если вообще передаётся) адрес машинной инструкции, вызвавший сбой, а не адрес, по которому инструкция обращалась к данным:

УМВР, есть и адрес упавшей инструкции, и адрес обращения к памяти. Это доступно в любой актуальной архитектуре где целесообразно запускать десктоп.

X512 ★★★★★
()
Ответ на: комментарий от LamerOk

Можно и штаны через голову надевать, но зачем?

Чтобы не падать по SIGBUS, а пытаться как-то его обработать. Напомню, что именно ты утверждал, что пользоваться нужно исключительно mmap.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

С прямыми руками SIGBUS прекрасно обрабатывается.

X512 ★★★★★
()
Ответ на: комментарий от Siborgium

Нет, это не 4.2. Оба приведенных примера сводятся к тому, что операция выполняется над адресом, который не относится к допустимым для записи.

Но в нашем-то разговоре адрес для записи в момент операции __ допустим __ с точки зрения пограммы. И твоё:

SIGBUS – об ошибке чтения-записи

– вопиющие 4.2.

При этом, если внимательно прочитать английский по ASCII, можно увидеть волшебную

Можно. Но это очевидное натягивание аппаратной совы на софтверный глобус и никто не будет работать с mmap’ом, обрабатывая сигналы. Эти сигналы - всего лишь вежливый способ убить программу, когда платформа не шмогла по какой-либо причине.

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от X512

УМВР

Я ни секунды не сомневаюсь. Но в стандарте английским по ASCII написано:

For some implementations, the value of si_addr may be inaccurate.

Иными словами - никаких гарантий в отношении этого поля в стандарте нет.

где целесообразно запускать десктоп

Какое отношение какой-то «десктоп» имеет к <signal.h>?

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от LamerOk

Можно. Но это очевидное натягивание аппаратной совы на софтверный глобус и никто не будет работать с mmap’ом, обрабатывая сигналы. Эти сигналы - всего лишь вежливый способ убить программу, когда платформа не шмогла по какой-либо причине.

Не только аппаратной. SIGBUS элементарно можно схватить при нехватке места на диске. По-твоему, программа не должна обрабатывать нехватку места на диске, а должна умирать при этом?

bigbit ★★★★★
()
Ответ на: комментарий от bigbit

SIGBUS элементарно можно схватить при нехватке места на диске. По-твоему, программа не должна обрабатывать нехватку места на диске, а должна умирать при этом?

SIGBUS не имеет никакого отношения к вводу / выводу данных на носители. А забота обеспечить программу памятью и синхронизировать отображённую в процесс память с каким-либо носителем, если это было задано при создании маппинга - это задача операционной системы.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

For some implementations, the value of si_addr may be inaccurate.

Зачем вам нужны эти реализации?

Какое отношение какой-то «десктоп» имеет к <signal.h>?

Такое что на других платформах signal.h может вообще не быть в виду невозможности реализации. Как и функции mmap.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от ox55ff

Иронично, что ты в попытке привести контрпример как раз и описал самый что ни на есть хрестоматийный пример говнокода :)

Выравнивание, паддинги и порядок байт в твоей структуре кто гарантировать будет? Десериализацию данных так не делают.

intelfx ★★★★★
()
Ответ на: комментарий от X512

Зачем вам нужны эти реализации?

Или мы пишем код согласно спецификации или мы понятно кто.

Такое что на других платформах signal.h может вообще не быть

И тогда весь поинт вешать обработчики сигналов при маппинге файла ещё больше теряет смысл.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Или мы пишем код согласно спецификации или мы понятно кто.

Никто не пишет код в соответствии спецификации Си. Используют спецификацию конкретного набора систем. Какие-нибудь особые системы с не 8 битными байтами, сегментацией и прочем волнуют только особых программистов встроенного софта.

И тогда весь поинт вешать обработчики сигналов при маппинге файла ещё больше теряет смысл.

Почему не пользоваться возможностями платформы тем более что это почти везде поддерживается? Зачем страдать из-за пары музейных железяк?

X512 ★★★★★
()
Ответ на: комментарий от intelfx

Выравнивание, паддинги и порядок байт в твоей структуре кто гарантировать будет?

pragma pack

X512 ★★★★★
()
Ответ на: комментарий от X512

Никто не пишет код в соответствии спецификации Си.

Но это не спецификация Си. Это спецификация Open Group, бывший POSIX.

Используют спецификацию конкретного набора систем.

Я тебя огорчу - «спецификации конкретных систем», например HP-UX или AIX - почти полная копипаста всё того же POSIX / Open Group (они за это деньги заплатили - имеют право). Причём, даже фраза «For some implementations, the value of si_addr may be inaccurate.» присутствует на соответствующих страницах.

Какие-нибудь особые системы с не 8 битными байтами, сегментацией и прочем волнуют только особых программистов

Системы-то может, и волнуют, но мы тут маппинг обсуждаем, и в частности mmap, а он существует в рамках конкретного стандарта - стандарта POSIX / Open Group. А с ним см. выше.

Почему не пользоваться возможностями платформы

Пользуйся на здоровье чем хочешь, только не утверждай что твоё решение для твоего локалхоста - это __ правильный __ способ.

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от LamerOk

SIGBUS не имеет никакого отношения к вводу / выводу данных на носители.

Имеет, об этом прямо написано в той самой цитате «английским по ACSII», которую тут выше приводили (..such as out-of-space condition).

А забота обеспечить программу памятью и синхронизировать отображённую в процесс память с каким-либо носителем, если это было задано при создании маппинга - это задача операционной системы.

mmap-то ОС сделает с большой радостью, только места на диске это не зарезервирует (sparse file). Если в момент записи в память на диске не окажется места, ты получишь SIGBUS.

bigbit ★★★★★
()
Ответ на: комментарий от LamerOk

Пользуйся на здоровье чем хочешь, только не утверждай что твоё решение для твоего локалхоста - это __ правильный __ способ.

Вы при всём желании не найдёте железо где si_addr не работает, но mmap есть. Без первого второе просто нельзя реализовать сколь-нибудь эффективно.

X512 ★★★★★
()
Ответ на: комментарий от bigbit

SIGBUS не имеет никакого отношения к вводу / выводу данных на носители.

Имеет, об этом прямо написано в той самой цитате

Нет, не имеет. В цитате написано в переводе на русский - «если имплементаторы обосруться сделать нормально, ваш процесс прибьют с каким-то левым сигналом».

SIGBUS - это, вообще-то, младший брат близнец SIGILL и старший брат SIGFPE. Все три сигнала - про корректность исполнения машинных инструкций. То, что «хакеры» - юниксоиды затыкают этими сигналами какие-то другие проблемы в каких-то других местах лишь показывает степень кривизны и ad-hoc’ности всего юниксового API.

mmap-то ОС сделает с большой радостью, только места на диске это не зарезервирует (sparse file)

Это и называется русскими словами «рукожопость» и «кривизна». Зачем нужна ОС, если она не даёт никаких гарантий в отношении исполняемого процесса?

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Зачем нужна ОС, если она не даёт никаких гарантий в отношении исполняемого процесса?

POSIX – это не ОС. В документации на Линукс не написано, что si_addr может возвращать ерунду на некоторых платформах: https://man7.org/linux/man-pages/man2/sigaction.2.html.

Я не понимаю к чему вы клоните? К тому что надо писать программы чтобы на любом калькуляторе работало? Или что UNIX-like убогие в целом системы и надо пользоваться Windows?

X512 ★★★★★
()
Ответ на: комментарий от bigbit

Ты еще спроси, зачем нужен overcommit

Спрошу. Overcommit не нужен и приводит к нестабильной работе программ.

X512 ★★★★★
()
Ответ на: комментарий от intelfx

Не знаешь про директиву, отключающую выравнивание? Порядок байт гарантирую я. Если уж есть спецификация на заголовок, то и порядок байт можно зафиксировать. Сотри свой высер.

ox55ff ★★★★★
()
Ответ на: комментарий от X512

Я не понимаю к чему вы клоните?

К тому, что SIGBUS не имеет никакого отношения к дисковой или сетевой подсистемам, и только упоротый наркоман может обрабатывать этот сигнал как ошибку ввода / вывода.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

К тому, что SIGBUS не имеет никакого отношения к дисковой или сетевой подсистемам

Имеет прямое отношение потому что mmap для файлов работает через обработчик page fault. По сути тот же signal, но в ядре. И без si_addr оно работать не будет.

X512 ★★★★★
()
Ответ на: комментарий от X512

Имеет прямое отношение

Ну, если ты настаиваешь, давай продолжим. Итак, надо ли нам обрабатывать ошибки чтения при mmap’е через обработчик SIGBUS?

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от LamerOk

Итак, надо ли нам обрабатывать ошибки чтения при mmap’е через обработчик SIGBUS?

Если надо чтобы программа не падала от ошибок чтения, то да.

X512 ★★★★★
()
Ответ на: комментарий от ox55ff

Не знаешь про директиву, отключающую выравнивание?

Ну то есть ты в итоге будешь зависеть и от компилятора со своей директивой, и от платформы с её порядком байт. Непортабельный говнокод как он есть, ЧТД.

intelfx ★★★★★
()
Ответ на: комментарий от LamerOk

Какая-нибудь утилита командной строки например. Программа которой не требуется работать длительное время.

X512 ★★★★★
()
Ответ на: комментарий от X512

Программа которой не требуется работать длительное время.

Стало быть любому юниксовому демону надо проверять ошибки чтения замапленного файла через обработчик SIGBUS’а?

LamerOk ★★★★★
()
Ответ на: комментарий от intelfx

Ну то есть ты в итоге будешь зависеть и от компилятора со своей директивой

На практике эта директива везде есть.

и от платформы с её порядком байт.

Big endian уже мёртв так что де факто везде единый порядок байт.

X512 ★★★★★
()
Ответ на: комментарий от LamerOk

Если требуется безотказная работа и его нельзя просто так перезапустить после падения без потери состояния, то да.

Может быть это уже делают в каких-нибудь nginx.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от X512

Стало быть любому юниксовому демону надо проверять ошибки чтения замапленного файла через обработчик SIGBUS’а?

Если требуется безотказная работа и его нельзя просто так перезапустить после подения без потери состояния, то да.

Красава. Теперь следи за руками:

  1. Линкер при старте маппит в память все файлы, из которых формируется исполняемый образ.
  2. Эти файлы с свою очередь при инициализации маппят в память файлы своих данных, локализации и др.

По твоей теории линкер на старте должен создавать обработчик SIGBUS’а, если не линкер - то инциализация райнтайма, если не она - то это надо делать в первой же строчке main(), но почему-то никто так не делает.

Почему все кругом дартаньяны, а ты один стоишь весь в белом?

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Красава. Теперь следи за руками:

Ситуацию запуска бинарника важного сервиса с битого диска обычно не предусматривают. Обработка ошибок mmap в первую очередь нужна для файлов из внешних источниках открытых самой программой.

X512 ★★★★★
()
Ответ на: комментарий от X512

Ну да. Все говнокодеры, когда пишут свой непортабельный говнокод, при этом приговаривают — «на самом деле всё нормально, все [известные мне] платформы и компиляторы ведут себя одинаково, никаких проблем нет». Сути происходящего, однако, это не меняет.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от X512

Обработка ошибок mmap

Но мы не говорим про обработку ошибок mmap - то есть обработку возвращаемых значений при вызове mmap и Ко. Мы говорим про хэндлер сигнала SIGBUS, который может, а может и не иметь отношение к замапленным файлам.

в первую очередь нужна для файлов из внешних источниках открытых самой программой.

Хорошо, какие базы данных или другие «долгоживущие» сервисы, которые маппят свои файлы данных устанавливают хэндлер SIGBUS’а для обработки ошибок чтения / записи данных с диска?

Ведь если это надо делать - это должна быть общепринятая практика, и её примеры легко нагуглить в открытых проектах. Не так ли?

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от LamerOk

Хорошо, какие базы данных или другие «долгоживущие» сервисы, которые маппят свои файлы данных устанавливают хэндлер SIGBUS’а для обработки ошибок чтения / записи данных с диска?

СУБД например.

X512 ★★★★★
()
Ответ на: комментарий от intelfx

Странно называть говнокодерами тех, кто эффективно пользуется возможностями платформы, тем более что это не какой-то редкий функционал, а массово доступный. Использование mmap и signal может приводить к многократному приросту производительности.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от intelfx

Gcc и clang поддерживают эту директиву. Что тебе ещё нужно? Вообще трудно себе представить системный компилятор, который не поддерживает управление выравниванием.

Порядок байт жёстко задан. Почитай например про про структуру заголовка ip пакетов. Там явно написано, что используется порядок байт BE вне зависимости от системы. Ну а я говорю, что у меня порядок байт LE. Проблемы?

Какая тебе портабельность нужна? Ты у себя в гараже откопал говно с BE? Ну так закапай назад.

ox55ff ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.