Контейнеры С++ STL непригодны для использования без исключений, что мы можем сделать по этому поводу?

Предполагаемый идеал С++ - это "то, что вы используете, вы платите". Однако это может быть довольно изнурительным из-за исключений и их повселокального использования в STL.

Прежде чем кто-нибудь скажет, что "просто включайте исключения", жизнь не настолько щедра с условиями программирования, в которых мы должны жить. Mine - это программирование ядра, где среда исполнения не обеспечивает достаточную рабочую среду С++ для разворачивания стека и т.д.

Контейнеры STL будут вызывать исключения при отказе выделения, если они не могут перераспределить хранилище для своих базовых хранилищ. Когда исключения не включены в среде, программа будет катастрофовать довольно загадочно: я видел, что реализация была отменена или просто предположила, что распределение работает, даже если это не так.

Многие библиотеки AD AD, с которыми я столкнулся, справляются с этой проблемой заранее, возвращая код ошибки или имея ошибку в качестве выходного параметра.

Что такое "лучший" С++ способ решения этой проблемы?

Чтобы уточнить

Я не хочу использовать стандартную библиотеку, я не могу. Я не спрашиваю: "Как я делаю то, что не может быть сделано". Я спрашиваю: "С учетом чистого листа, как должна строиться библиотека контейнеров".

Ответ 1

Это легко: перестаньте верить, что вы должны использовать стандартную библиотеку для всего.

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

Стандартный механизм С++ для сбоя сигнализации, в частности, что-то вроде выделения внутренней памяти из контейнера, заключается в том, чтобы выбросить исключение. Подавляющее большинство приложений не потрудились поймать это исключение; в маловероятном случае, когда у них не хватает памяти, они просто умирают. Это нормально для них. Возврат кода ошибки в этих случаях в лучшем случае сложнее (рассмотрите вопрос о перераспределении std::vector<std::string>. Что произойдет, если один из внутренних std::string - это то, что получает OOM? Кто получает код ошибки? Как бы вы даже сигнализировали о сбое конструктор, поскольку исключение выбрано std::string конструктором копирования?). И только люди, которым действительно нужно заботиться, будут заботиться о том, чтобы их поймать.

Вы работаете в ограниченной среде, среде, в которой стандартная библиотека не предназначена для обработки. Поэтому... не используйте его в этой среде.

Я предлагаю отследить копию EASTL. Это действительно предназначено для такого рода вещей. Репо Github я связал вас с некоторыми исправлениями ошибок и т.д., Но он по-прежнему в основном тот же. Это не плохой код. Их STL-подобные контейнеры обеспечивают большую часть интерфейса, поэтому они могут быть в основном заменой замены. Но они обеспечивают специальную функциональность, которая специально контролирует выделение памяти. И они не бросают (или, по крайней мере, вы можете отключить метание).

Ответ 2

Кажется, проблема в вашей среде. Скручивание стека не очень сложно. Я могу понять, почему вы хотели бы наложить на него некоторые ограничения - выброс объекта с 10 МБ является законным С++, но даже в режиме ядра вы сможете поддерживать металирование std::bad_alloc через не виртуальные вызовы.

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