В различных источниках встречаются упоминания того, что нельзя использовать идентификаторы с несколькими подчеркиваниями, или что нельзя называть параметры шаблона _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
то никакие имена, определенные в стандартных заголовочных файлах не помешают определить X
Также стандартная библиотека может использовать имена вида ::_f в своей реализации, тогда конфликт имен приведет к нарушению One Definition Rule, что обычно проявляется в виде ошибок линковки.
C
Аналогичные правила используются и в Си.
В главе "7.1.3 Reserved identifiers" приведен список зарезервированных идентификаторов:
все которые начинаются с _ и следующей за ним большой буквы или _
те которые начинаются с _ в области видимости файла, и находятся в обычном пространстве имен или пространстве имен тегов (в отличие от С++, разрешено двойное подчеркивание в середине и в конце имени);
имена макросов, приведенные в стандарте, если переопределение не разрешено явно;
имена с внешним связыванием, приведенные в стандарте, зарезервированы для имен с внешним связыванием;
имена из стандартных заголовочных файлов, если подключен соответствующий заголовочный файл.
Комментариев нет:
Отправить комментарий