11.1 Определяемое реализацией поведение ¶
Это то, как CPP ведёт себя во всех случаях, которые стандарт C описывает как определяемое реализацией. Это означает, что реализация свободна действовать по своему усмотрению, но обязана задокументировать свой выбор и придерживаться его.
- Сопоставление физических символов многобайтовых кодовых страниц исходного файла с кодовой страницей выполнения.
Кодовая страница ввода может быть указана с помощью опции -finput-charset, а кодовая страница выполнения может контролироваться с помощью опций -fexec-charset и -fwide-exec-charset.
- Символы идентификаторов.
Стандарты C и C++ разрешают идентификаторы, состоящие из символа ‘_’ и буквенно-цифровых символов. C++ также разрешает универсальные имена символов. Стандарты C99 и более поздние стандарты C допускают как универсальные имена символов, так и определяемые реализацией символы. В режимах C и C++, GCC принимает в идентификаторах ровно те расширенные символы, которые соответствуют универсальным именам символов, разрешённым выбранным стандартом.
GCC разрешает символ ‘$’ в идентификаторах как расширение для большинства целевых платформ. Это верно независимо от переключателя std=, поскольку это расширение не может конфликтовать с программами, соответствующими стандарту. Однако при предварительной обработке ассемблера по умолчанию символы доллара не являются символами идентификаторов.
В настоящее время целевые платформы, которые по умолчанию не допускают ‘$’, — это AVR, IP2K, MMIX, MIPS Irix 3, ARM aout и PowerPC-целевые платформы для операционной системы AIX.
Вы можете переопределить значение по умолчанию с помощью -fdollars-in-identifiers или fno-dollars-in-identifiers. См. fdollars-in-identifiers.
- Непустые последовательности пробельных символов.
В текстовом выводе каждая последовательность пробельных символов сводится к одному пробелу. По эстетическим соображениям первый токен на каждой строке без директив вывода предваряется достаточным количеством пробелов, чтобы он отображался в той же колонке, что и в исходном файле.
- Числовое значение символьных констант в выражениях препроцессора.
Препроцессор и компилятор интерпретируют символьные константы одинаково; т. е. escape-последовательности, такие как ‘\a’, получают значения, которые они имели бы на целевой машине.
Компилятор оценивает многосимвольную символьную константу по одному символу за раз, сдвигая предыдущее значение влево на количество битов на символ целевой платформы, а затем объединяет битовую модель нового символа, усеченного до ширины символа целевой платформы. Конечная битовая модель имеет тип
int, и поэтому является знаковым, независимо от того, являются ли отдельные символы знаковыми или нет. Если в константе больше символов, чем помещается в целевомint, компилятор выводит предупреждение, и избыточные ведущие символы игнорируются.Например,
'ab'для целевой платформы с 8-битнымcharинтерпретируется как ‘(int) ((unsigned char) 'a' * 256 + (unsigned char) 'b')’, а'\234a'как ‘(int) ((unsigned char) '\234' * 256 + (unsigned char) 'a')’. - Включение исходных файлов.
Обсуждение того, как препроцессор находит файлы заголовков, см. в Функционирование включения.
- Интерпретация имени файла, полученного в результате макроподстановки директивы ‘#include’.
- Обработка директивы ‘#pragma’, которая после макроподстановки приводит к стандартной директиве #pragma.
Никакой макроподстановки не происходит для любой строки директивы ‘#pragma’, поэтому этот вопрос не возникает.
Обратите внимание, что GCC пока не реализует ни одну из стандартных директив #pragma.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.5.0/cpp/Implementation-defined-behavior.html