Контейнеры C++ STL непригодны для использования без исключений, что мы можем с этим поделать?
Предполагаемый идеал C++ - "то, за что вы платите". Однако это может быть довольно изнурительным из-за исключений и их повсеместного использования в STL.
Прежде чем кто-то скажет "просто включите исключения", жизнь не настолько щедра к средам программирования, в которых мы должны жить. Мой - это программирование ядра, где среда выполнения не обеспечивает достаточно времени выполнения C++ для размотки стека и т. Д.
Контейнеры STL будут генерировать исключения ошибок выделения, когда они не смогут перераспределить хранилище для своих базовых хранилищ. Когда исключения не включены в среде, программа будет работать довольно таинственно: я видел, как реализации прерывали работу или просто предполагали, что распределение работало, даже если это не так.
Многие библиотеки C ADT, с которыми я сталкивался, решают эту проблему заранее, возвращая код ошибки или имея ошибку в качестве выходного параметра.
Каков "лучший" C++ способ решения этой проблемы?
Уточнить
Я не хочу использовать стандартную библиотеку, я не могу. Я не спрашиваю "как мне сделать то, что не может быть сделано". Я спрашиваю: "с чистого листа, как должна быть построена библиотека контейнеров".
2 ответа
Это просто: перестаньте верить, что вам следует использовать стандартную библиотеку для всего.
Стандартная библиотека предназначена для использования по умолчанию для функциональности. Однако это не означает, что это уместно в любой ситуации. Например, программирование ядра. Это довольно нишевая среда, где вам нужен прямой и явный контроль над вещами, которые не волнуют большинство программистов на C++.
Стандартный механизм C++ для сигнализации о сбое, особенно при выделении внутренней памяти из контейнера, - это исключение. Подавляющее большинство приложений не потрудится поймать это исключение; в том маловероятном случае, если у них не будет памяти, они просто умрут. Что хорошо для них. Возврат кода ошибки в этих случаях в лучшем случае затруднителен (рассмотрим перераспределение std::vector<std::string>
, Что будет, если один из внутренних std::string
s это то, что получает OOM? Кто получает код ошибки? Как бы вы даже сигнализировали об отказе конструктора, так как исключение выдается std::string
Копировать конструктор?). И только люди, которые действительно нуждаются в заботе, будут заботиться достаточно, чтобы поймать это.
Вы работаете в ограниченной среде, среде, для которой стандартная библиотека не предназначена. Так что... не используйте его в этой среде.
Я предлагаю выследить копию EASTL. Он действительно предназначен для такого рода вещей. В репозитории Github, с которым я вас связал, есть исправления ошибок и т. Д., Но в большинстве случаев это то же самое. Это неплохой код. Их STL-подобные контейнеры обеспечивают большую часть интерфейса, поэтому они могут быть в основном заменой. Но они предоставляют специальные функциональные возможности для конкретного управления распределением памяти. И они не бросают (или, по крайней мере, вы можете отключить бросание).
Кажется, проблема действительно в вашей среде. Разматывание стека не очень сложно. Я могу понять, почему вы хотите наложить на него некоторые ограничения - использование 10 МБ объекта является допустимым C++, но даже в режиме ядра вы должны иметь возможность поддерживать сброс std::bad_alloc
через не виртуальные звонки.
Имея это в виду, дизайн STL совершенно вменяемый. Интерфейс требует минимальной поддержки исключений, а реализация может быть адаптирована к среде.