mirror of
https://github.com/Nekrolm/ubbook.git
synced 2025-12-18 13:14:41 +03:00
reserved names
This commit is contained in:
@@ -68,10 +68,11 @@
|
|||||||
7. [Разыменование nullptr](runtime/nullptr_dereference.md)
|
7. [Разыменование nullptr](runtime/nullptr_dereference.md)
|
||||||
8. [Static initialization order fiasco](runtime/static_initialization_order_fiasco.md)
|
8. [Static initialization order fiasco](runtime/static_initialization_order_fiasco.md)
|
||||||
9. [ODR violation](runtime/odr_violation.md)
|
9. [ODR violation](runtime/odr_violation.md)
|
||||||
10. [Тривиальные типы и ABI](runtime/trivial_types_and_ABI.md)
|
10. [Зарезервированные имена](runtime/reserved_names.md)
|
||||||
11. [Неинициализированные переменные](runtime/uninitialized.md)
|
11. [Тривиальные типы и ABI](runtime/trivial_types_and_ABI.md)
|
||||||
12. [Ranges. Unreachable sentinel](runtime/unreachable_sentinel.md)
|
12. [Неинициализированные переменные](runtime/uninitialized.md)
|
||||||
13. [Невиртуальные виртуальные функции](runtime/virtual_functions.md)
|
13. [Ranges. Unreachable sentinel](runtime/unreachable_sentinel.md)
|
||||||
|
14. [Невиртуальные виртуальные функции](runtime/virtual_functions.md)
|
||||||
7. Происхождение указателей
|
7. Происхождение указателей
|
||||||
1. [Невалидные указатели](pointer_prominence/invalid_pointer.md)
|
1. [Невалидные указатели](pointer_prominence/invalid_pointer.md)
|
||||||
2. [Placement `operator new[]`](pointer_prominence/array_placement_new.md)
|
2. [Placement `operator new[]`](pointer_prominence/array_placement_new.md)
|
||||||
|
|||||||
55
runtime/reserved_names.md
Normal file
55
runtime/reserved_names.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Зарезервированные имена
|
||||||
|
|
||||||
|
Эта тема тесно связана с [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 <iostream>
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user