# Preprocessore C ++ che definisce una parola chiave. È conforms agli standard?

Aiuta a risolvere il dibattito che sta succedendo nei commenti a questa domanda su bool e 1 :

Un preprocessore C ++ conforms agli standard consente di utilizzare #define per ridefinire una parola chiave della lingua? In tal caso, è necessario un preprocessore C ++ conforms agli standard?

Se un programma C ++ ridefinisce una parola chiave della lingua, può il programma stesso essere conforms agli standard?

In C ++, la cosa più vicina alla proibizione #define una parola chiave è §17.4.3.1.1 / 2, che non è consentita solo in un’unità di traduzione che include un’intestazione di libreria standard:

Un’unità di traduzione che include un’intestazione non deve contenere alcuna macro che definisca i nomi dichiarati o definiti in quell’intestazione. Né tale unità di traduzione definirà le macro per i nomi lessicalmente identici alle parole chiave.

La seconda frase di quel paragrafo è stata cambiata in C ++ 0x per vietare a #define una parola chiave (C ++ 0x FCD §17.6.3.3.1):

Un’unità di traduzione non deve #define o #undef nomi identicamente lessicali alle parole chiave.

Modifica: come sottolineato da Ken Bloom nei commenti alla sua risposta , le regole non sono cambiate in C ++ 0x; il testo è stato appena riorganizzato per confondere le persone come me. 🙂

Lavorando dalla bozza di lavoro C ++ del 2005-10-19 (poiché non ho uno standard a portata di mano):

La Sezione 16.3 definisce la grammatica per #define come #define identifier replacement-list-newline (macro object-like) o una delle diverse costruzioni che iniziano con #define identifier lparen (macro funzione-like). identifier s sono definiti nella sezione 2.10 per essere identifier-nondigit | identifier identifier-nondigit | identifier digit identifier-nondigit | identifier identifier-nondigit | identifier digit identifier-nondigit | identifier identifier-nondigit | identifier digit . La Sezione 2.11 indica che un certo elenco di identificatori viene trattato incondizionatamente come parole chiave nella fase 7 della compilazione (sezione 2.1), e concludo che non sono quindi trattati in modo speciale nella fase 4, che è l’espansione del preprocessore. Pertanto, sembra che lo standard richieda il preprocessore per consentire di ridefinire le parole chiave della lingua (elencate nella Sezione 2.11) .

Tuttavia, il preprocessore ha una propria parola chiave, vale a dire defined , nonché un elenco di macro predefinite (Sezione 16.8). Sezione 16.8 afferma che il comportamento non è definito se si ridefiniscono questi, ma non impedisce al preprocessore di riconoscerli come nomi di macro.