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-6.5.0/cpp/Differences-from-previous-versions.html