Д. Стефенс - C++. Сборник рецептов Страница 30
- Категория: Компьютеры и Интернет / Программирование
- Автор: Д. Стефенс
- Год выпуска: -
- ISBN: -
- Издательство: -
- Страниц: 136
- Добавлено: 2019-05-29 11:12:08
Д. Стефенс - C++. Сборник рецептов краткое содержание
Прочтите описание перед тем, как прочитать онлайн книгу «Д. Стефенс - C++. Сборник рецептов» бесплатно полную версию:Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
Д. Стефенс - C++. Сборник рецептов читать онлайн бесплатно
Главной причиной, по которой от компиляторов не требуется отвергать все некорректно написанные программы, является то, что во многих случаях эту некорректность сложно, а иногда и невозможно обнаружить. Еще одной причиной, которая обсуждается далее, является то, что некорректные с точки зрения стандарта программы иногда очень полезны.
Я советую вам использовать опции строгого соответствия компилятора как можно чаще. Однако имеются ситуации, когда это невозможно. Чтобы лучше это понять, давайте посмотрим на несколько вариантов не соответствующего стандарту кода.
Для начала вот код, который полностью попустим в ранних диалектах С++, существовавших до стандартизации языка. Например, в ранних версиях C++ область видимости переменной, объявленной при инициализации цикла for, простиралась до конца блока, в котором находился этот цикл.
// ВНИМАНИЕ: некорректный код!
int main() {
for (int i = 0; i < 10; ++i)
;
int j = i; // j == 10
}
Стандартом это не допускается и не имеет никаких преимуществ по сравнению со стандартными правилами областей видимости. Требование компилировать код, подобный этому, возникает только при сопровождении устаревших приложений.
Другой категорией некорректного кода является код, который использует экспериментальные расширения языка, которые по какой-либо причине не вошли в конечный стандарт C++. Например, многие компиляторы предоставляют встроенный тип long long, длина которого гарантированно имеет не менее 64 бит. Как еще один пример, некоторые компиляторы предоставляют встроенный оператор typeof, имеющий такой же синтаксис, как и оператор sizeof, и возвращающий тип выражения. Обе эти функции, скорее всего, появятся в следующей версии стандарта C++, хотя ожидается, что написание typeof изменится на, возможно, decltype.
Будьте осторожны при использовании подобного рода расширений: вы можете столкнуться с тем, что вам потребуется портировать код на платформу, не реализующую какого-либо расширения или реализующую его по-другому.
Третья категория некорректного кода — это код, который использует платформенно-зависимые расширения языка, необходимые для использования функций операционной системы. В эту категорию попадают атрибуты __declspec(dllexport) и __declspec(dllimport), используемые для сборки динамических библиотек в Windows, и атрибуты __stdcall, __fastcall и __cdecl, представляющие соглашения о вызовах в Windows. Хотя это и расширения языка, большая часть компиляторов для Windows принимает код, содержащий эти расширения, даже если используется опция строгого соответствия стандарту.
Последней категорией некорректного кода является код, нарушающий стандарт С++, но полностью соответствующий некоторым другим стандартам. Главным примером такого стандарта является C++/CLI, который сейчас проходит последние стадии стандартизации в ECMA. C++/CLI — это расширение С++, которое состоит из интерфейса C++ к Command Language Infrastructure — ядру Microsoft .NET Framework. При компиляции приложения, использующего определенные расширения C++/CLI, соответствующий стандарту компилятор C++ должен выдавать диагностику, но при поддержке стандарта C++/CLI он может свободно генерировать работоспособное приложение.
Если вам требуется скомпилировать код, не соответствующий стандарту, вначале проверьте, будет ли он компилироваться при использовании опций, приведенных в табл. 1.37 и 138. Если нет, то некоторые компиляторы предлагают набор «дробных» опций совместимости, позволяющих использовать некоторые несовместимые конструкции, но запрещающих другие. Например, Comeau предоставляет опцию --long_long, указывающую на необходимость распознавания типа long long. Наконец, некоторые компиляторы предоставляют опции, заставляющие их сообщать о большинстве нарушений стандарта как о предупреждениях, а не ошибках. Например, GCC для этой цели предоставляет опцию -pedantic, a Comeau для Windows предоставляет опцию --a, а для других платформ — опции --strict_warnings или -a.
Смотри такжеРецепт 1.2.
1.25. Указание определенной библиотеки для автоматической компоновки с исходным файлом
ПроблемаВы написали библиотеку, которую хотите распространять в виде набора заголовочных файлов и готовых статических или динамических библиотек, но не хотите, чтобы пользователи вашей библиотеки должны были сами указывать имена библиотек при компоновке приложений.
РешениеПри программировании для Windows с использованием инструментария Visual C++, Intel, Metrowerks, Borland или Digital Mars для указания имен и (при необходимости) путей готовых библиотек, с которыми должен компоноваться код, включающий заголовочные файлы вашей библиотеки, используйте в этих заголовочных файлах pragma comment.
Например, предположим, что вы хотите распространить библиотеку из примера 1.1, состоящую из статической библиотеки libjohnpaul.lib и заголовочного файла johnpaul.hpp. Измените этот заголовочный файл так, как показано в примере 1.26.
Пример 1.26. Использование pragma comment
#ifndef JОНNPAUL_HPP_INCLUDED
#define JOHNPAUL_HPP_INCLUDED
#pragma comment(lib, "libjohnpaul")
void johnpaul();
#endif // JOHNPAUL_HPP_INCLUDED
После этого изменения компоновщики Visual С++, Intel, Metrowerks, Borland и Digital Mars при компоновке кода, включающего заголовочный файл johnpaul.hpp, будут автоматически находить библиотеку libjohnpaul.lib.
ОбсуждениеВ некоторых ситуациях компоновка может оказаться более сложным этапом процесса сборки, чем компиляция. Одна из наиболее часто возникающих проблем компоновки создается тогда, когда компоновщик находит неверную версию какой-либо библиотеки. Это в основном проблема Windows, где библиотеки времени выполнения и зависящие ar них библиотеки часто имеют множество вариантов. По этой причине библиотеки для Windows часто поставляются с именами, измененными так, чтобы они отражали различные конфигурации сборки. Хотя это и помогает снизить число конфликтов версий, это также затрудняет процесс компоновки, так как теперь вы должны указывать компоновщику правильное измененное имя.
По этой причине pragma comment очень полезна. Среди прочего она позволяет указать правильное имя библиотеки в заголовочном файле и избавить пользователя от необходимости разбираться в ваших соглашениях об изменении имен файлов. Если в дополнение к этому вы разработаете процесс установки, копирующий двоичные файлы в папку, автоматически используемую компоновщиком, — такую как поддиректория lib корневых директорий Visual С++, CodeWarrior или C++Builder, — то программисты смогут использовать вашу библиотеку, просто включив ее заголовочные файлы.
До сих пор все было хорошо. Но есть одна проблема: pragma comment распознается не всеми компиляторами. Если вы хотите писать портируемый код, вы должны вызывать pragma только после того, как проверите, что она поддерживается используемым инструментарием. Например, вы можете изменить johnpaul.cpp вот так.
#ifndef JOHNPAUL_HPP_INCLUDED
#define JOHNPAUL_HPP_INCLUDED
#if defined(_MSC_VER) || \
defined(__ICL) || \
defined(__MWERKS__) && defined(_WIN32) || \
defined(__BORLANDC__) \
defined(__DMC__) \
/**/
#pragma comment (lib, "libjohnpaul")
#endif
void johnpaul();
#endif // JOHNPAUL_HPP_INCLUDED
Этот пример уже стал достаточно сложным, и, к сожалению, он все еще не полностью корректен: некоторые компиляторы, не поддерживающие pragma comment, для совместимости в Visual C++ определяют макрос _MSC_VER. К счастью, Boost предоставляет простое решение.
#ifndef johnpaul_hpp_included
#define JOHNPAUL_HPP_INCLUDED
#define BOOST_LIB_NAME libjohnpaul
#define BOOSTAUTO_LINK_NOMANGLE
#include <boost/config/auto_link.hpp>
void johnpaul();
#endif // JOHNPAUL_HPP_INCLUDED
Здесь строка
#define BOOST_LIB_NAME libjohnpaul
определяет имя библиотеки, строка
#define BOOST_AUTO_LINK_NOMANGLE
указывает, что вы не хотите использовать соглашение об именах Boost, а строка
#include <boost/config/auto_link.hpp>
вызывает pragma comment для поддерживающих ее компиляторов.
Смотри такжеРецепт 1.23.
1.26. Использование экспортируемых шаблонов
ПроблемаВы хотите собрать программу, использующую экспортируемые шаблоны, что означает, что она объявляет шаблоны в заголовочных файлах с использованием ключевого слова export, а реализация шаблонов находится в файлах .cpp.
РешениеВо-первых, скомпилируйте в объектные файлы файлы .cpp, содержащие реализации шаблонов, передав компилятору опцию командной строки, необходимую для включения экспортируемых шаблонов. Затем скомпилируйте и скомпонуйте файлы .cpp, использующие экспортируемые шаблоны, передав компилятору и компоновщику опции командной строки, необходимые для включения экспортируемых шаблонов, а также опции, указывающие директории, содержащие реализации шаблонов.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.