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.
- Непустые последовательности символов пробелов.
В текстовом выводе каждая последовательность пробелов сводится к одному пробелу. По эстетическим соображениям, первому токену на каждой недирективе строки вывода предшествует достаточное количество пробелов, чтобы он отображался в той же колонке, что и в исходном файле.
- Числовое значение символьных констант в выражениях препроцессора.
Препроцессор и компилятор интерпретируют символьные константы одинаково; т.е. последовательности экранирования, такие как ‘\a’, получают значения, которые они имели бы на целевой машине.
Компилятор оценивает многосимвольную символьную константу символ за символом, сдвигая предыдущее значение влево на количество битов на символ целевой платформы, а затем объединяя в нем битовое представление нового символа, усеченного до ширины символа целевой платформы. Конечное битовое представление получает тип
int, и, следовательно, является знаковым, независимо от того, являются ли отдельные символы знаковыми или нет. Если в константе больше символов, чем помещается в целевомint, компилятор выдает предупреждение, а избыточные ведущие символы игнорируются.Например,
'ab'для целевой платформы с 8-битнымcharинтерпретировалось бы как ‘(int) ((unsigned char) 'a' * 256 + (unsigned char) 'b')’, а'\234a'как ‘(int) ((unsigned char) '\234' * 256 + (unsigned char) 'a')’. - Включение исходных файлов.
Для обсуждения того, как препроцессор находит файлы заголовков, см. Include Operation.
- Интерпретация имени файла, полученного в результате макроподстановки директивы ‘#include’.
- Обработка директивы ‘#pragma’, которая после макроподстановки приводит к стандартной прагме.
Никакой макроподстановки не происходит для какой-либо строки директивы ‘#pragma’, поэтому вопрос не возникает.
Обратите внимание, что GCC пока не реализует ни одну из стандартных прагм.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/cpp/Implementation-defined-behavior.html