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