11.4 Отличия от предыдущих версий
В этом разделе подробно описаны изменения поведения по сравнению с предыдущими версиями CPP. Мы не планируем менять его в ближайшем будущем, но и не обещаем, что не будем этого делать.
«Предыдущие версии», о которых здесь говорится, — это 2.95 и более ранние. Поведение GCC 3.0 в основном такое же, как поведение широко используемых снимков разработки 2.96 и 2.97. Там, где есть различия, они обычно представляют собой ошибки в снимках.
- -I- устаревшее
Этот параметр устарел в версии 4.0. -iquote призван заменить необходимость этого параметра.
- Порядок вычисления операторов ‘#’ и ‘##’
Стандарт не определяет порядок вычисления цепочки операторов ‘##’, а также не указывает, вычисляется ли ‘#’ до, после или одновременно с ‘##’. Поэтому вы не должны писать код, который зависит от какого-либо конкретного порядка. Можно гарантировать порядок, если он необходим, с помощью соответствующего использования вложенных макросов.
Пример, где это может иметь значение, — склеивание аргументов ‘1’, ‘e’ и ‘-2’. Это было бы хорошо для склеивания слева направо, но склеивание справа налево привело бы к созданию недопустимого токена ‘e-2’.
GCC 3.0 вычисляет ‘#’ и ‘##’ одновременно и строго слева направо. Более ранние версии вычисляли все операторы ‘#’ сначала, а затем все операторы ‘##’ в ненадежном порядке.
- Формат пробелов между токенами в выходных данных препроцессора
См. Выходные данные препроцессора, чтобы узнать о текущем текстовом формате. Это также формат, используемый для строкового отображения. Обычно препроцессор передает токены напрямую в анализатор компилятора, и пробелы вообще не возникают.
Более ранние версии GCC сохраняли все пробелы, предоставленные пользователем, и вставляли еще много своих пробелов, потому что они не могли точно предсказать, когда дополнительные пробелы были необходимы, чтобы предотвратить случайное склеивание токенов.
- Необязательный аргумент при вызове макросов с остаточными аргументами
В качестве расширения GCC разрешает вам полностью опустить переменные аргументы при использовании макроса с переменным числом аргументов. Это запрещено стандартом C 1999, и это вызовет педантичное предупреждение в GCC 3.0. Предыдущие версии принимали это молча.
- ‘##’ поглощает предшествующий текст в макросах с остаточными аргументами
Ранее, при макроподстановке, если ‘##’ появлялся перед параметром переменного числа аргументов, и множество токенов, указанных для этого аргумента в вызове макроса, было пустым, предыдущие версии CPP возвращались назад и удаляли предшествующую последовательность символов, не являющихся пробелами (не предшествующий токен). Это расширение напрямую противоречит стандарту C 1999 и было существенно сокращено.
В текущей версии препроцессора, если ‘##’ появляется между запятой и параметром переменного числа аргументов, а аргумент переменного числа опущен полностью, запятая будет удалена из расширения. Если аргумент переменного числа пуст или токен перед ‘##’ не является запятой, то ‘##’ ведет себя как обычная операция склеивания токенов.
- ‘#line’ и ‘#include’
Директива ‘#line’ раньше изменяла представление GCC о «каталоге, содержащем текущий файл», используемом в ‘#include’ с именем заголовочного файла в двойных кавычках. В 3.0 и более поздних версиях этого не происходит. Смотрите Управление строками для получения дополнительного объяснения.
- Синтаксис ‘#line’
В GCC 2.95 и предыдущих версиях строковый константный аргумент ‘#line’ обрабатывался так же, как и аргумент ‘#include’: обратные слэши не учитывались, а строка заканчивалась на второй ‘"’. Это не соответствует стандарту C. В GCC 3.0 была предпринята попытка исправить поведение, чтобы строка обрабатывалась как реальная строковая константа, но оказалось, что это имело ошибки. В 3.1 ошибки были исправлены. (Мы не исправляем ошибки в 3.0, потому что они затрагивают относительно небольшое количество людей, а исправление довольно инвазивное.)
Предыдущее: Устаревшие функции, Вверх: Детали реализации [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/cpp/Differences-from-previous-versions.html