﻿# Прощай \#define private public

Язык C\+\+, компиляторы и библиотеки движутся всё больше в сторону ужесточения контроля того, что пишет программист\. Это хорошо\. Все наверное слышали шутки вот на эту тему: \#define true \(\(rand\(\) % 100\) < 95 ? true : false\)\. Шутки, шутками, но возможность переопределить ключевые слова иногда приводит к значительному затруднению понимания программы или непонятным ошибкам\.

В новой Visual Studio 11 сделана проверка для выявления переопределения ключевых слов\. Для этого в файле xkeycheck\.h имеется следующий текст:

```cpp
#else /* __cplusplus is defined */ 
#if defined(alignas) /* check C++ keywords */ \ 
|| defined(alignof) \ 
|| defined(asm) \ 
|| defined(auto) \ 
|| defined(bool) \ 
|| defined(break) \ 
|| defined(case) \ 
|| defined(catch) \ 
|| defined(char) \ 
|| defined(char16_t) \ 
|| defined(char32_t) \ 
|| defined(class) \ 
|| defined(const) \ 
|| defined(const_cast) \ 
|| defined(constexpr) \ 
|| defined(continue) \ 
|| defined(decltype) \ 
|| defined(default) \ 
|| defined(delete) \ 
|| defined(do) \ 
|| defined(double) \ 
|| defined(dynamic_cast) \ 
|| defined(else) \ 
|| defined(enum) \ 
|| defined(explicit) \ 
|| defined(export) \ 
|| defined(extern) \ 
|| defined(false) \ 
|| defined(float) \ 
|| defined(for) \ 
|| defined(friend) \ 
|| defined(goto) \ 
|| defined(if) \ 
|| defined(inline) \ 
|| defined(int) \ 
|| defined(long) \ 
|| defined(mutable) \ 
|| defined(namespace) \ 
|| defined(new) && defined(_ENFORCE_BAN_OF_MACRO_NEW) \ 
|| defined(noexcept) \ 
|| defined(nullptr) \ 
|| defined(operator) \ 
|| defined(private) \ 
|| defined(protected) \ 
|| defined(public) \ 
|| defined(register) \ 
|| defined(reinterpret_cast) \ 
|| defined(return) \ 
|| defined(short) \ 
|| defined(signed) \ 
|| defined(sizeof) \ 
|| defined(static) \ 
|| defined(static_assert) \ 
|| defined(static_cast) \ 
|| defined(struct) \ 
|| defined(switch) \ 
|| defined(template) \ 
|| defined(this) \ 
|| defined(thread_local) \ 
|| defined(throw) \ 
|| defined(true) \ 
|| defined(try) \ 
|| defined(typedef) \ 
|| defined(typeid) \ 
|| defined(typename) \ 
|| defined(union) \ 
|| defined(unsigned) \ 
|| defined(using) \ 
|| defined(virtual) \ 
|| defined(void) \ 
|| defined(volatile) \ 
|| defined(wchar_t) \ 
|| defined(while) 
#error keyword defined before including C++ standard header 
#endif /* defined... */ 
#endif /* defined(__cplusplus) */ 
#endif /* RC_INVOKED */ 
#endif /* _XKEYCHECK_H */
```



Если вы планируете в скором будущем использовать Visual C\+\+ 11, то можно заранее постараться исправить код, где используется переопределение ключевых слов\. Чаще всего это применяется в различных тестах\. Например, чтобы в тестах получить доступ к закрытым членам классов, используются следующий приём:

```cpp
#define private public
#define protected public
```

Теперь этот код скомпилирован не будет\. Мы, например, встретили такую ошибку, при попытке собрать с помощью Visual C\+\+ 11 исходные коды игры Doom 3 \(файл TypeInfo\.cpp\)\.

Желаем вам поменьше использовать различных обманных приёмов\. Они экономят время в краткосрочной перспективе, но рано или поздно всплывают при смене платформы/компилятора и их приходится переписывать\.