Хотя это, безусловно, будет «работать», и вам в значительной степени гарантировано, что «настоящий» UB не вызывается, но я думаю, что на букву стандарта, можно утверждать, что Undefined Behavior вызываетсяВ соответствии с длительными и несколько неоднозначными разработками [lex]
.
Точно так же нет никакого "реального вреда" в совершении чего-то вроде #define __included_foo_h
или struct bar { int _Data; };
, но стандарт прямо говорит в [lex.name]
что эти имена зарезервированы. Что, как ни крути, это именно то, что есть.
Сколько бы это ни стоило, стандартная библиотека постоянно использует такие имена, как __data
или __begin
, поэтому, очевидно, нет никаких серьезных технических причинсделать это. Только ... стандартная библиотека является частью реализации, и ваша программа не обладает такой свободой . Так что, да, это, вероятно, вообще не имеет значения, но вам все равно не разрешено это делать (если только из-за опасений, что вы можете нарушить функциональность стандартной библиотеки в очень неочевидном, невозможном для отладки)образом).
В частности:
[lex.key]
Идентификаторы, показанные в таблице 5, зарезервированы для использования в качестве ключевых слов (то естьони безусловно обрабатываются как ключевые слова в фазе 7), за исключением токена атрибута
[lex.phases]
7. Символы пробела, разделяющие токены, более не имеют значения. Каждый токен предварительной обработки преобразуется в токен. Полученные токены синтаксически и семантически анализируются и переводятся как единица перевода.
Правда, в фазе 4 происходят макро-замены, поэтому фаза 7 не будет "видеть" переопределенное ключевое слово как таковое. Тем не менее, он четко говорит «зарезервировано» и «безусловно». Итак, если вам было позволено просто игнорировать это на основе «но компилятор не видит», то вы могли бы, например, #define __inline inline [[gnu:always_inline]]
с той же логикой. Кому интересно, если зарезервированы двойные подчеркивания, компилятор этого не видит!
Не думаю, что, хотя это, безусловно, будет «работать», это строго законная точка зрения.
(Забавный факт: я однажды использовал #define private public
, работал как шарм.)