Каковы допустимые символы для имен макросов?
Подпадают ли имена макросов в стиле C под те же правила именования, что и идентификаторы? После обновления компилятора теперь выдается это предупреждение для устаревшего приложения:
warning #3649-D: white space is required between the macro name "CHAR_" and its replacement text
#define CHAR_& 38
Эта строка кода определяет константу значения ASCII для амперсанда.
#define DOL_SN 36
#define PERCENT 37
#define CHAR_& 38
#define RT_SING 39
#define LF_PAR 40
Я предполагаю, что это определение (на самом деле не ссылается ни на какой код, насколько я могу судить) содержит ошибки и должно быть заменено чем-то вроде "CHAR_AMPERSAND"?
4 ответа
Имена макросов должны состоять только из буквенно-цифровых символов и символов подчеркивания, т.е. 'a-z'
, 'A-Z'
, '0-9'
, а также '_'
и первый символ не должен быть цифрой. Некоторые препроцессоры также допускают символ знака доллара '$'
, но вы не должны его использовать; к сожалению, я не могу процитировать стандарт C, так как у меня нет его копии.
Из документации GCC:
Токены предварительной обработки делятся на пять широких классов: идентификаторы, числа предварительной обработки, строковые литералы, знаки препинания и другие. Идентификатор такой же, как идентификатор в C: любая последовательность букв, цифр или подчеркиваний, которая начинается с буквы или подчеркивания. Ключевые слова C не имеют значения для препроцессора; они обычные идентификаторы. Например, вы можете определить макрос, именем которого является ключевое слово. Единственный идентификатор, который можно считать ключевым словом предварительной обработки,
defined
, См. Определено.Это в основном верно для других языков, которые используют препроцессор Си. Тем не менее, некоторые ключевые слова в C++ важны даже в препроцессоре. Смотрите C++ Именованные Операторы.
В стандарте C 1999 года идентификаторы могут содержать буквы, которые не являются частью "базового исходного набора символов", по усмотрению реализации (например, акцентированные латинские буквы, греческие буквы или китайские идеограммы). Это может быть сделано с расширенным набором символов или
'\u'
а также'\U'
escape последовательности Реализация этой функции в GCC является экспериментальной; такие символы принимаются только в'\u'
а также'\U'
формы и только если-fextended-identifiers
используется.В качестве расширения GCC рассматривает
'$'
как письмо. Это для совместимости с некоторыми системами, такими как VMS, где'$'
обычно используется в системных именах функций и объектов.'$'
не является буквой в строго соответствующем режиме, или если вы указываете-$
вариант. Смотрите Invocation.
clang
позволяет много "сумасшедших" персонажей.. хотя я изо всех сил пытался найти какой-либо много рифмы или причины - относительно того, почему некоторые разрешены, а другие нет. Например..
#define ?: /// WORKS FINE
#define ■ @end /// WORKS FINE
#define @interface /// WORKS FINE
#define P @protocol /// WORKS FINE
еще
#define ☎ TEL /// ERROR: Macro name must be an identifier.
#define ❌ NO /// ERROR: Macro name must be an identifier.
#define ⇧ UP /// ERROR: Macro name must be an identifier.
#define 〓 == /// ERROR: Macro name must be an identifier.
#define APPLE /// ERROR: Macro name must be an identifier.
Кто знает. Я бы с удовольствием... но Google пока что подвел меня. Любое понимание предмета, будет оценено ™ ™.
Вы правы, те же правила применяются к макросу и идентификаторам, что касается имен: допустимые символы [A-Za-z0-9_].
Обычно используются ЗАГЛАВНЫЕ имена, чтобы отличать макросы от других идентификаторов - переменных и имени функции.
Те же правила, которые определяют допустимые идентификаторы для имен переменных, применяются к именам макросов, за исключением того, что макросы могут иметь те же имена, что и ключевые слова. Допустимые символы в именах идентификаторов включают digits
а также non-digits
и не должен начинаться с цифры. non-digits
включают заглавные буквы AZ, строчные буквы az, подчеркивание и любые символы, определенные реализацией.