Pré-processador de C ++ # define uma palavra-chave. É norma em conformidade?

Ajude a resolver o debate que está acontecendo nos comentários desta pergunta sobre bool e 1 :

Um pré-processador C ++ em conformidade com os padrões permite usar o #define para redefinir uma palavra-chave? Em caso afirmativo, um pré-processador C ++ em conformidade com os padrões deve permitir isso?

Se um programa C ++ redefinir uma palavra-chave de linguagem, esse programa pode estar em conformidade com os padrões?

Em C ++, o mais próximo de proibir #define definir uma palavra-chave é o §17.4.3.1.1 / 2, que apenas a desativa em uma unidade de tradução que inclui um header de biblioteca padrão:

Uma unidade de tradução que inclui um header não deve conter macros que definam nomes declarados ou definidos nesse header. Nem tal unidade de tradução deve definir macros para nomes lexicalmente idênticos a palavras-chave.

A segunda frase desse parágrafo foi alterada em C ++ 0x para proibir completamente #definir uma palavra-chave (C ++ 0x FCD §17.6.3.3.1):

Uma unidade de tradução não deve # definir ou #undef nomes lexicalmente idênticos a palavras-chave.

Edit: Como apontado por Ken Bloom em comentários à sua resposta , as regras não foram alteradas em C ++ 0x; o texto acaba de ser rearranjado para confundir pessoas como eu. 🙂

Trabalhando a partir do draft de trabalho em C ++ de 2005-10-19 (já que não tenho um padrão acessível):

A seção 16.3 define a gramática para #define como #define identifier replacement-list-newline (macros de tipo object) ou uma de várias construções começando com #define identifier lparen (macros de function semelhante). identifier são definidos na seção 2.10 como identifier-nondigit | identifier identifier-nondigit | identifier digit identifier-nondigit | identifier identifier-nondigit | identifier digit identifier-nondigit | identifier identifier-nondigit | identifier digit . A Seção 2.11 indica que uma certa lista de identificadores é tratada incondicionalmente como palavras-chave na fase 7 de compilation (seção 2.1), e concluo que elas não são tratadas especialmente na fase 4, que é a expansão do pré-processador. Assim, parece que o padrão requer que o pré-processador permita que você redefina as palavras-chave da linguagem (listadas na Seção 2.11) .

No entanto, o pré-processador possui uma palavra-chave própria, defined como uma lista de macros predefinidas (Seção 16.8). A Seção 16.8 afirma que o comportamento é indefinido se você os redefinir, mas não proíbe o pré-processador de reconhecê-los como nomes de macro.