Страницы

Поиск по вопросам

понедельник, 8 октября 2018 г.

Правила использования подчеркивания “_” в именах

В различных источниках встречаются упоминания того, что нельзя использовать идентификаторы с несколькими подчеркиваниями, или что нельзя называть параметры шаблона _Ty При этом заголовочных файлах стандартной библиотеки только такие имена и используются. Почему так? Как надо писать правильно?


Ответ

C++
В главе Identifiers [lex.name] сказано, что некоторые идентификаторы зарезервированы, и могут быть использованы только компилятором и стандартной библиотекой:
зарезервировано любое имя, которое содержит двойное подчеркивание (__), или начинается с подчеркивания и следующей за ним большой буквой; в глобальном пространстве имен, зарезервировано любое имя, которое начинается с подчеркивания.
В случае если эти правила нарушены, компилятор не обязан выдавать какие-либо ошибки или предупреждения, поведение программы не определено.
Примеры:
void _f(); // запрещено class X { int _m; // OK int _M; // запрещено }; namespace N { int _1; // OK void _f(); // OK class X__Y; // запрещено }
Почему так сделано?
Это дает гарантию, что имена в стандартной библиотеке не будут пересекаться с пользовательским кодом. Например если написать
#define X struct Y; #include
то определение имен X и Y ничего не сломают в стандартных заголовочных файлах, и наоборот, если написать
#include struct X;
то никакие имена, определенные в стандартных заголовочных файлах не помешают определить X
Также стандартная библиотека может использовать имена вида ::_f в своей реализации, тогда конфликт имен приведет к нарушению One Definition Rule, что обычно проявляется в виде ошибок линковки.
C
Аналогичные правила используются и в Си. В главе "7.1.3 Reserved identifiers" приведен список зарезервированных идентификаторов:
все которые начинаются с _ и следующей за ним большой буквы или _ те которые начинаются с _ в области видимости файла, и находятся в обычном пространстве имен или пространстве имен тегов (в отличие от С++, разрешено двойное подчеркивание в середине и в конце имени); имена макросов, приведенные в стандарте, если переопределение не разрешено явно; имена с внешним связыванием, приведенные в стандарте, зарезервированы для имен с внешним связыванием; имена из стандартных заголовочных файлов, если подключен соответствующий заголовочный файл.

Комментариев нет:

Отправить комментарий