Описание

Данный проект представляет собой полную стандартную библиотеку C++ от SGI, «адаптированную» мной для использования в MFC-приложениях, разрабатываемых в среде Microsoft Visual C++ 6.0. Основные изменения, внесенные в официальный вариант библиотеки, доступный на сайте SGI, заключаются в следующем:

  • отладочный вариант библиотеки использует средства контроля корректности работы с динамической памятью, предоставляемые отладочной версией CRT; при этом учитывается переопределение оператора new в отладочной версии MFC;
  • отладочный вариант библиотеки использует malloc_alloc в качестве аллокатора по умолчанию, что предотвращает ложные сообщения отладчика Visual C++ об утечках памяти;
  • автоматически используется реализация потоков ввода/вывода «нового стиля», соответствующая стандарту ISO/IEC 14882:1998 (библиотека содержит последний development snapshot от SGI, датированный 08.06.2000);
  • добавлены «оболочки» заголовочных файлов стандартной библиотеки C (cassert, cctype, etc) — в соответствии с разделом 17.4.1.2 стандарта ISO/IEC 14882:1998.

Примечание: все эти изменения доступны также при использовании компилятора C++ от Intel; естественно, что собирать библиотеку и использующее ее приложение нужно одним и тем же компилятором.

Установка и сборка

vc98-tree.gifУстановка библиотеки заключается в распаковке архива sgi-stl-src.zip с ее исходными текстами в произвольную папку на жестком диске, доступную компилятору и компоновщику (я предпочитаю использовать для этого папку VC98, которая создается при установке Microsoft Visual C++ 6.0, как показано на рисунке справа). При желании вы можете также скачать и распаковать архив sgi-stl-doc.zip, содержащий авторскую документацию к библиотеке в формате HTML Help 1.x.

Предусмотрены две сборочные конфигурации: «Win32 – Debug» и «Win32 – Release», созданные на основе «Win32 (x86) Static Library» и подразумевающие использование динамических версий CRT и MFC. Для сборки библиотеки необходимо перейти в «корневую» папку STL (содержащую файл libcio.mak) и воспользоваться утилитой nmake, выполнив команды

nmake /f "libcio.mak" CFG="libcio - Win32 Debug"
nmake /f "libcio.mak" CFG="libcio - Win32 Release"

соответствующие отладочной и «чистовой» конфигурациям. После этого в папке lib будут доступны файлы libciod.lib и libcio.lib, содержащие реализацию потокового ввода/вывода.

Настройка интегрированной среды

Для использования библиотеки при сборке и отладке приложений в интегрированной среде Visual C++ необходимо:

  1. Находясь в меню Tools выполнить команду Options… и в открывшемся диалоговом окне Options перейти на вкладку Directories.
  2. Выбрать в списке Show directories for: пункт Include files и добавить в список Directories: полный путь к заголовочным файлам библиотеки (…\STL\include), поместив его перед путем к стандартным заголовочным файлам Visual C++ (…\VC98\Include).
  3. Выбрать пункт Library files и добавить в список Directories: полный путь к файлам, содержащим реализацию потоков ввода/вывода (…\STL\lib), поместив его перед путем к стандартным библиотечным файлам Visual C++ (…\VC98\Lib).
  4. Выбрать пункт Source files и добавить в список Directories: полные пути к исходным файлам библиотеки (…\STL\source, …\STL\include и …\STL\include\bits), поместив их перед путем к исходным файлам CRT (…\VC98\CRT\SRC).

Использование в проектах

Сразу оговоримся, что SGI STL ничем не отличается от любой другой библиотеки — для ее использования необходимо включить требуемые заголовочные файлы и указать компоновщику на соответствующий библиотечный модуль (диалоговое окно Project Settings, вкладка Link, категория General, поле Object/library modules). Поэтому все сказанное ниже носит исключительно рекомендательный характер и основывается на личном опыте.

  • Для подавления «annoying warnings» (термин MS) компилятора можно использовать директиву #pragma warning; заметим, что в случае предупреждения C4786 эта директива должна располагаться до первой директивы #include.
  • Для заголовочных файлов STL целесообразно устанавливать уровень предупреждений не выше 3; соответственно, если для всего проекта в целом установлен более высокий уровень предупреждений, то его можно снизить/восстановить с помощью директив #pragma warning.
  • Код, генерируемый компилятором Visual C++ 6.0, «бросает» исключение bad_cast из глобального пространства имен (а не из пространства имен std, как того требует стандарт), поэтому следующий текст
    class First { ... };
    class Second { ... };
    
    try
    {
       First* pFirst = new First();
       dynamic_cast<Second&>(*pFirst);
       delete pFirst;
    }
    catch (const std::bad_cast& xcpt)
    {
       cout << xcpt.what() << endl;
    }
    catch (const std::exception& xcpt)
    {
       cout << xcpt.what() << endl;
    }
    
    нормально компилируется, но приводит к поимке std::exception. Для устранения этой проблемы можно включить заголовочный файл <typeinfo.h> (вместо стандартного <typeinfo>) перед прочими заголовочными файлами стандартной библиотеки и «ввести» bad_cast в пространство имен std при помощи директивы using. (Большое спасибо Павлу Кузнецову за помощь в решении данной проблемы.)
  • При использовании потоков ввода/вывода необходимо предотвратить конфликт с библиотекой импорта msvcprt.lib (или msvcprtd.lib в отладочной версии), ссылка на которую автоматически включается компилятором в объектные модули — для этого можно воспользоваться директивой #pragma comment, позволяющей внедрять в код ключи командной строки для компоновщика. Эту же директиву можно использовать и для указания библиотеки, содержащей реализацию потоков ввода/вывода от SGI, в исходном тексте приложения (а не в настройках проекта).

Фрагмент файла StdAfx.h:

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// unreferenced inline/local function has been removed
#pragma warning(disable: 4514)
// function not inlined
#pragma warning(disable: 4710)
// identifier was truncated in the debug information
#pragma warning(disable: 4786)

// MFC core and standard components
#include <afxwin.h>

// TODO: reference additional headers your program requires here

#pragma warning(push, 3)
#if _MSC_VER <= 1200
#include <typeinfo.h>
namespace std { using ::bad_cast; }
#else
#include <typeinfo>
#endif
#include <vector>
#include <map>
#include <iostream>
#pragma warning(pop)

Фрагмент файла StdAfx.cpp:

#include "StdAfx.h"

#if defined(_DEBUG)
#pragma comment(linker, "/nodefaultlib:msvcprtd.lib")
#pragma comment(lib, "libciod.lib")
#else
#pragma comment(linker, "/nodefaultlib:msvcprt.lib")
#pragma comment(lib, "libcio.lib")
#endif

Дистрибутивы

download.gif Исходные тексты: sgi-stl-src.zip (444 060 байт).
download.gif Документация: sgi-stl-doc.zip (701 064 байта).

обновлено
15.03.2006
 
Проверка PR и ТИЦ