Главной причиной, по которой от компиляторов не требуется отвергать все некорректно написанные программы, является то, что во многих случаях эту некорректность сложно, а иногда и невозможно обнаружить. Еще одной причиной, которая обсуждается далее, является то, что некорректные с точки зрения стандарта программы иногда очень полезны.
Я советую вам использовать опции строгого соответствия компилятора как можно чаще. Однако имеются ситуации, когда это невозможно. Чтобы лучше это понять, давайте посмотрим на несколько вариантов не соответствующего стандарту кода.
Для начала вот код, который полностью попустим в ранних диалектах С++, существовавших до стандартизации языка. Например, в ранних версиях 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. Указание определенной библиотеки для автоматической компоновки с исходным файлом
Проблема
Вы написали библиотеку, которую хотите распространять в виде набора заголовочных файлов и готовых статических или динамических библиотек, но не хотите, чтобы пользователи вашей библиотеки должны были сами указывать имена библиотек при компоновке приложений.
Читать дальше