Законно ли переопределять ключевое слово C ++? - PullRequest
11 голосов
/ 02 февраля 2012

В этой статье от Гуру недели сказано: It is illegal to #define a reserved word. Это правда?Я не могу найти ничего в норме, и я уже видел программистов, переопределяющих, например, новое.

Ответы [ 5 ]

19 голосов
/ 02 февраля 2012

17.4.3.1.1 Имена макросов [lib.macro.names]

1 Каждое имя, определенное как макрос в заголовке, зарезервировано для реализации для любого использования.если блок перевода включает заголовок.164)
2 Блок перевода, который включает заголовок, не должен содержать макросов, которые определяют имена, объявленные или определенные в этом заголовке. Кроме того, такая единица перевода не должна определять макросы для имен, лексически идентичных ключевым словам.

Кстати, new является оператором и может быть перегружен (заменен) наПользователь, предоставив свою версию.

11 голосов
/ 02 февраля 2012

Соответствующий раздел из C ++ 11:

17.6.4.3.1 Имена макросов [macro.names]

1 Модуль перевода, который включает стандартный заголовок библиотеки, не должен объявлять имена #define или #undef, объявленные в любом стандартном заголовке библиотеки.
2 Единица перевода не должна называть имена #define или #undef лексически идентичными ключевым словам.

Пункт 1 из C ++ 03 был удален. Второй абзац был разделен на две части. Первая половина теперь была изменена, чтобы указать, что она применяется только к стандартным заголовкам. Второй пункт был расширен и теперь включает любые единицы перевода, а не только те, которые содержат заголовки.

Однако Обзор для данного раздела стандарта ( 17.6.4.1 [constraints.overview] ) гласит:

В этом разделе описаны ограничения для программ на C ++, использующих средства стандартной библиотеки C ++.

Поэтому, если вы не используете стандартную библиотеку C ++, тогда вы можете делать то, что хотите.

Итак, чтобы ответить на ваш вопрос в контексте C ++ 11: вы не можете определить (или отменить определение) любые имена, идентичные ключевым словам в любой единице перевода, если вы используете стандартную библиотеку C ++.

2 голосов
/ 16 декабря 2015

Они там на самом деле не правы или, по крайней мере, не рассказывают всей истории об этом. Настоящая причина, по которой он запрещен, заключается в том, что он нарушает правило одного определения (которое, кстати, также упоминается как вторая причина, почему оно незаконно).

Чтобы увидеть, что на самом деле разрешено (переопределять ключевые слова), по крайней мере, если вы не используете стандартные библиотеки, вам нужно взглянуть на совершенно другую часть стандарта, а именно на этапы перевода. Это говорит о том, что входные данные раскладываются только в токены препроцессора до того, как происходит предварительная обработка, и, глядя на те, между private и fubar нет различия, они оба identifiers для препроцессора. Позже, когда входная информация разлагается на token, замена уже произошла.

Было отмечено, что существует ограничение на программы, которые должны использовать стандартные библиотеки, но не очевидно, что пример, переопределяющий private, делает это (в отличие от «Лица № 4: Языковой адвокат»). фрагмент, который использует его для вывода на cout).

В последнем примере упоминается, что уловка не попирает другие единицы перевода или не попирает другие. Имея это в виду, вам, вероятно, следует рассмотреть возможность использования стандартной библиотеки где-то еще, что приведет к введению этого ограничения.

2 голосов
/ 10 декабря 2012

Вот кое-что, что вы можете сделать, если не хотите, чтобы кто-то использовал goto.Просто поместите следующее где-нибудь в своем коде, где он этого не заметит.

#define goto { int x = *(int *)0; } goto

Теперь каждый раз, когда он пытается использовать оператор goto, его программа падает.

0 голосов
/ 02 февраля 2012

Это не так далеко, насколько я знаю, незаконно - ни один компилятор, с которым я сталкивался, пока не выдаст ошибку, если вы сделаете

#define true false

#defining некоторые ключевые слова могут вызывать ошибки при компиляции по другим причинам. Но многие из них приведут к очень странному поведению программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...