C++. Сборник рецептов
Шрифт:
Ни один из компиляторов не может обеспечить полного соответствия стандарту с точки зрения отказа компилировать любую неверную программу. И не только из-за того, что ни один из них не соответствует стандарту на 100%: более важной причиной является то, что стандарт C++ не требует от компилятора отвергать неверные программы. Имеется четкий перечень обстоятельств, в которых компилятор должен выдавать диагностическое сообщение, указывающее на неправильно написанную программу, однако для многих некорректных программ диагностики не требуется. Это программы, которые приводят к тому, что стандарт называет неопределенным поведением
Главной причиной, по которой от компиляторов не требуется отвергать все некорректно написанные программы, является то, что во многих случаях эту некорректность сложно, а иногда и невозможно обнаружить. Еще одной причиной, которая обсуждается далее, является то, что некорректные с точки зрения стандарта программы иногда очень полезны.
Я советую вам использовать опции строгого соответствия компилятора как можно чаще. Однако имеются ситуации, когда это невозможно. Чтобы лучше это понять, давайте посмотрим на несколько вариантов не соответствующего стандарту кода.
Для начала вот код, который полностью попустим в ранних диалектах С++, существовавших до стандартизации языка. Например, в ранних версиях C++ область видимости переменной, объявленной при инициализации цикла
Стандартом это не допускается и не имеет никаких преимуществ по сравнению со стандартными правилами областей видимости. Требование компилировать код, подобный этому, возникает только при сопровождении устаревших приложений.
Другой категорией некорректного кода является код, который использует экспериментальные расширения языка, которые по какой-либо причине не вошли в конечный стандарт C++. Например, многие компиляторы предоставляют встроенный тип
Будьте осторожны при использовании подобного рода расширений: вы можете столкнуться с тем, что вам потребуется портировать код на платформу, не реализующую какого-либо расширения или реализующую его по-другому.
Третья категория некорректного кода — это код, который использует платформенно-зависимые расширения языка, необходимые для использования функций операционной системы. В эту категорию попадают атрибуты
Последней категорией некорректного кода является код, нарушающий стандарт С++, но полностью соответствующий некоторым другим стандартам. Главным примером такого стандарта является C++/CLI, который сейчас проходит последние стадии стандартизации в ECMA. C++/CLI — это расширение С++, которое состоит из интерфейса C++ к Command Language Infrastructure — ядру Microsoft .NET Framework. При компиляции приложения, использующего определенные расширения C++/CLI, соответствующий стандарту компилятор C++ должен выдавать диагностику, но при поддержке стандарта C++/CLI он может свободно генерировать работоспособное приложение.
Если вам требуется скомпилировать код, не соответствующий стандарту, вначале проверьте, будет ли он компилироваться при использовании опций, приведенных в табл. 1.37 и 138. Если нет, то некоторые компиляторы предлагают набор «дробных» опций совместимости, позволяющих использовать некоторые несовместимые конструкции, но запрещающих другие. Например, Comeau предоставляет опцию – -long_long, указывающую на необходимость распознавания типа
Рецепт 1.2.
1.25. Указание определенной библиотеки для автоматической компоновки с исходным файлом
Вы написали библиотеку, которую хотите распространять в виде набора заголовочных файлов и готовых статических или динамических библиотек, но не хотите, чтобы пользователи вашей библиотеки должны были сами указывать имена библиотек при компоновке приложений.
При программировании для Windows с использованием инструментария Visual C++, Intel, Metrowerks, Borland или Digital Mars для указания имен и (при необходимости) путей готовых библиотек, с которыми должен компоноваться код, включающий заголовочные файлы вашей библиотеки, используйте в этих заголовочных файлах
Например, предположим, что вы хотите распространить библиотеку из примера 1.1, состоящую из статической библиотеки libjohnpaul.lib и заголовочного файла johnpaul.hpp. Измените этот заголовочный файл так, как показано в примере 1.26.
Пример 1.26. Использование pragma comment
После этого изменения компоновщики Visual С++, Intel, Metrowerks, Borland и Digital Mars при компоновке кода, включающего заголовочный файл johnpaul.hpp, будут автоматически находить библиотеку libjohnpaul.lib.