Контейнеры C ++ STL непригодны для использования без исключений, что мы можем с этим поделать? - PullRequest
15 голосов
/ 25 марта 2012

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

Прежде чем кто-либо скажет «просто включите исключения», жизнь не настолько щедра к средам программирования, в которых мы должны жить.программирование ядра, где среда выполнения не предоставляет достаточно времени выполнения C ++ для размотки стека и т. д.

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

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

Каков «лучший» C ++ способ решения этой проблемы?

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

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

Ответы [ 2 ]

18 голосов
/ 25 марта 2012

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

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

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

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

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

3 голосов
/ 26 марта 2012

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

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

...