Большинство изменений кода SGI в реализации STLport связано с улучшением переносимости, однако STLport является единственной известной мне реализацией, в которой предусмотрен «отладочный режим» для диагностики случаев неправильного использования STL — компилируемых, но приводящих к непредсказуемым последствиям во время работы программы. Например, в совете 30 распространенная ошибка записи за концом контейнера поясняется следующим примером:
int transmogrify(int х); // Функция вычисляет некое новое значение
// по переданному параметру х
vector values;
… // Заполнение вектора values данными
vector results;
transform(values.begin(), // Попытка записи за концом results!
values.end(), results.end, transmogrify);
Этот фрагмент компилируется, но во время выполнения работает непредсказуемо. Если вам повезет, проблемы возникнут при вызове transform
, и отладка будет относительно элементарной. Гораздо хуже, если вызов transform
испортит данные где-то в другом месте адресного пространства, но это обнаружится лишь позднее. В этом случае определение причины порчи данных становится задачей — как бы выразиться? — весьма нетривиальной.
Отладочный режим STLport значительно упрощает эту задачу. При выполнении приведенного выше вызова transform
выдается следующее сообщение (предполагается, что реализация STLport установлена в каталоге C:\STLport):
C:\STLport\stlport\stl\debug\_iterator.h:265 STL assertion failure: _Dereferenceable(*this)
На этом программа прекращает работу, поскольку в случае ошибки отладочный режим STLport вызывает abort
. Если вы предпочитаете, чтобы вместо этого инициировалось исключение, STLport можно настроить и на этот режим.
Честно говоря, приведенное сообщение об ошибке менее понятно, чем хотелось бы, а имя файла и номер строки относятся к внутренней проверке условия STL, а не к строке с вызовом transform
, но это все же значительно лучше пропущенного вызова transform
и последующих попыток разобраться в причинах разрушения структур данных. В отладочном режиме STLport остается лишь запустить программу-отладчик, вернуться по содержимому стека к написанному вами коду и определить, что же произошло. Строка, содержащая ошибку, обычно находится достаточно легко.
Отладочный режим STLport распознает широкий спектр стандартных ошибок, в том числе передачу алгоритмам недопустимых интервалов, попытки чтения из пустого контейнера, передачу итератора одного контейнера в качестве аргумента функции другого контейнера и т. д. Волшебство основано на взаимном отслеживании итераторов и контейнеров. При наличии двух итераторов это позволяет проверить, принадлежат ли они одному контейнеру, а при модификации контейнера — определить, какие итераторы становятся недействительными.
В отладочном режиме реализация STLport использует специальные реализации итераторов, поэтому итераторы vector
и string
являются объектами классов, а не низкоуровневыми указателями. Таким образом, использование STLport и компиляция в отладочном режиме помогают убедиться в том, что ваша программа не игнорирует различия между указателями и итераторами для соответствующих типов контейнеров. Одной этой причины может оказаться достаточно для того, чтобы познакомиться с отладочным режимом STLport.
В 1997 году завершился процесс, приведший к появлению Международного стандарта C++. Многие участники были разочарованы тем, что возможности, за которые они выступали, не прошли окончательный отбор. Некоторые из этих участников были членами самого Комитета, поэтому они решили разработать основу для дополнения стандартной библиотеки во время второго круга стандартизации. Результатом их усилий стал сайт Boost, который был призван «предоставить бесплатные библиотеки C++. Основное внимание уделяется переносимым библиотекам, соответствующим Стандарту C++». За этой целью кроется конкретный мотив:
По мере того как библиотека входит в «повседневную практику», возрастает вероятность того, что кто-нибудь предложит ее для будущей стандартизации. Предоставление библиотеки на сайт Boost.org является одним из способов создания «повседневной практики»…
Иначе говоря, Boost предлагается в качестве механизма, помогающего отделить плевелы от зерен в области потенциальных дополнений стандартной библиотеки C++. Вполне достойная миссия, заслуживающая нашей благодарности.
Читать дальше