# Зарезервированные имена Эта тема тесно связана с [ODR violation](odr_violation.md). В C/C++ невероятно много идентификаторов, использовать которые для своих переменных и типов запрещено под страхом неопределенного поведения. Некоторые имена запрещены самим стандартом C/C++. Некоторые — стандартами POSIX. Некоторые — платформоспецифическими библиотеками. В последнем случая обычно вам ничего не грозит, пока библиотека не подключена. Так в глобальной области видимости нельзя использовать имена функций из библиотеки C. Ни в C, ни в C++! Иначе вы можете столкнуться не только с ODR-violation, но еще и с удивительным поведением компиляторов, умеющих оптимизировать распространенные конструкции. Так, если определить свой собственный `memset`: ```C void *memset (void *destination, int c, unsigned long n) { for (unsigned long i = 0; i < n; ++i) { ((char*)(destination))[i] = c; } return destination; } ``` Заботливый оптимизирующий компилятор может запросто [превратить](https://godbolt.org/z/fKfeqza6a) его в ```C void *memset (void* destination, int c, unsigned long n) { return memset(destination, c, n); } ``` В C++, благодаря включенному по умолчанию декорированию имен, рекурсии не будет — вызовется стандартный `memset`, вместо нашего. Однако, декорирование не спасает, если объявлять не функции, а глобальные переменные. ```C++ #include int read; int main(){ std::ios_base::sync_with_stdio(false); std::cin >> read; } ``` При сборке такого примера со статически влинкованной стандартной библиотекой C, программа [упадет](https://godbolt.org/z/sq9bqhn46). Так как вместо адреса стандартной функции `read` будет подставлен адрес глобальной переменной `read`. Аналогичный пример с использованием имени `write` предлагается читателю воплотить самостоятельно в качестве упражнения. Запретных имен много. Например, все, что начинается с `is*`, `to*` или `_*` запрещено в глобальном пространстве. `_[A-Z]*` запрещены вообще везде. POSIX резервирует имена, заканчивающиеся на `_t`. И еще много всего неожиданного. С более полными списками можно ознакомиться по ссылкам. Если вы пользуетесь запрещенными именами, то сегодня может всё работать, но не завтра. Чтобы не жить в страхе во многих случаях достаточно использовать `static` или анонимные пространства имен. Или просто не использовать C/C++. ## Полезные ссылки 1. https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html 2. https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier 3. https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL51-CPP.+Do+not+declare+or+define+a+reserved+identifier