Pergunta

Eu criei um novo projeto com o segmento de código a seguir:

char* strange = "(Strange??)";
cout << strange << endl;

resultando na seguinte resultado:

(Estranho]

Assim traduzir '??)' -> ']'

Depuração mostra que o meu char * string literal é realmente esse valor e não é uma tradução fluxo. Isso obviamente não é uma seqüência meta-personagem que eu já vi. Algum tipo de Unicode ou seqüência de char ampla talvez? Eu não penso assim no entanto ... Eu tentei desabilitar todas as configurações do projeto relacionados sem sucesso.

Alguém tem uma explicação?

  • pesquisa: 'ponto de interrogação, ponto de interrogação, perto cinta' c c ++ string literal
Foi útil?

Solução

O que você está vendo é chamado trigraph .

Na linguagem escrita por adultos, um ponto de interrogação é suficiente para qualquer situação. Não use mais de um de cada vez e você nunca vai ver isso novamente.

GCC ignora trigraphs por padrão porque quase ninguém usa-los intencionalmente. Capacitá-los com a opção -trigraph, ou dizer ao compilador para avisá-lo sobre eles com a opção -Wtrigraphs.

Visual C ++ 2010 também desativa-los por padrão e ofertas /Zc:trigraphs para habilitá-los. Eu não consigo encontrar nada sobre maneiras de ativar ou desativar-los em versões anteriores.

Outras dicas

Fácil maneira de evitar a surpresa trigraph: dividir um "??" literal de cadeia em dois:

char* strange = "(Strange??)";
char* strange2 = "(Strange?" "?)";
/*                         ^^^ no punctuation */

Editar
gcc tem uma opção para avisar sobre trigraphs: -Wtrigraphs (habilitado com -Wall também)
editar final

Cotações do padrão

    5.2.1.1 Trigraph sequences
1   Before any other processing takes place, each occurrence of one of the
    following sequences of three characters (called trigraph sequences13))
    is replaced with the corresponding single character.
           ??=      #               ??)      ]               ??!      |
           ??(      [               ??'      ^               ??>      }
           ??/      \               ??<      {               ??-      ~
    No other trigraph sequences exist. Each ? that does not begin one of
    the trigraphs listed above is not changed.
    5.1.1.2 Translation phases
1   The precedence among the syntax rules of translation is specified by
    the following phases.
         1.   Physical source file multibyte characters are mapped, in an
              implementation-defined manner, to the source character set
              (introducing new-line characters for end-of-line indicators)
              if necessary. Trigraph sequences are replaced by corresponding
              single-character internal representations.

É um Trigraph !

??) é um trigraph .

É trigraph apoio. Você pode evitar interpretação trigraph escapando qualquer um dos caracteres:

char* strange = "(Strange?\?)";

É um trigraph .

Trigraphs são a razão. A conversa sobre C no artigo também se aplica a C ++

Como mencionado várias vezes, você está sendo mordido por um trigraph. Veja esta pergunta SO anterior para mais informações:

Você pode corrigir o problema usando o '\?' seqüência de escape para o '?' caracteres:

char* strange = "(Strange\?\?)";

Na verdade, esta é a razão para essa seqüência de escape, o que é um tanto misteriosa Se você está inconsciente daqueles trigraphs malditos.

Ao tentar cruzar-compilação no GCC ele pegou minha sequência como uma trigraph :

Assim, todos necessidade I de fazer agora é descobrir como desativar isso em projetos por padrão desde que eu só posso vê-lo a criar problemas para mim. (Estou usando um layout de teclado US anyway)

O comportamento padrão no GCC é ignorar, mas dar um aviso, que é muito mais sã e é realmente o que Visual Studio 2010 adotará como o padrão, tanto quanto eu sei.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top