Pergunta

De acordo com o C++'03 Standard 2.3/1:

Antes de qualquer outro processamento ocorre, a cada ocorrência de uma das seguintes sequências de três caracteres ("trigraph sequências") é substituída por um único caractere indicado na Tabela 1.

----------------------------------------------------------------------------
| trigraph | replacement | trigraph | replacement | trigraph | replacement |
----------------------------------------------------------------------------
| ??=      | #           | ??(      | [           | ??<      | {           |
| ??/      | \           | ??)      | ]           | ??>      | }           |
| ??’      | ˆ           | ??!      | |           | ??-      | ˜           |
----------------------------------------------------------------------------

Na vida real, o que significa que o código printf( "What??!\n" ); vai resultar na impressão What| porque ??! é um trigraph sequência que é substituído com o | o personagem.

A minha pergunta é qual a finalidade de usar trigraphs? Existe alguma vantagem prática de usar trigraphs?

UPD:Nas respostas foi mencionado que alguns teclados Europeus não têm todos os caracteres de pontuação, de modo que não NOS programadores tem que usar trigraphs na vida cotidiana?

UPD2:O Visual Studio 2010 tem trigraph apoio desativada por padrão.

Foi útil?

Solução

Essa pergunta (sobre intimamente relacionados digraphs) tem a resposta.

Resume-se ao fato de que a ISO 646 conjunto de caracteres não tem todos os caracteres da sintaxe C, então existem alguns sistemas com teclados e monitores que não pode lidar com os personagens (apesar de eu imaginar que esses são muito raros hoje em dia).

Em geral, você não precisa usá-los, mas você precisa saber sobre eles para exatamente o problema que você correu para dentro.Trigraphs são a razão de a a a '?'personagem tem uma seqüência de escape:

'\?'

Por isso, algumas maneiras que você pode evitar o problema de exemplo são:

 printf( "What?\?!\n" ); 

 printf( "What?" "?!\n" ); 

Mas você tem que lembrar de quando você está digitando dois '?' caracteres que você pode estar começando um trigraph (e isso certamente não é algo que eu estou pensando).

Na prática, trigraphs e digraphs são algo que eu não me preocupar em um dia-a-dia.Mas você deve estar ciente deles, porque uma vez a cada dois anos, você vai correr em um bug relacionado a eles (e você vai passar o resto do dia a maldição de sua existência).Seria bom se os compiladores pode ser configurado para avisar (ou de erro) quando ele vem através de um trigraph ou dígrafo, para que eu pudesse saber que eu tenho algo que eu deveria lidar conscientemente com.

E só para completar, digraphs são muito menos perigosas, pois são processadas como tokens, assim, um dígrafo dentro de um literal de cadeia de caracteres, não começar interpretado como um dígrafo.

Para uma boa educação em vários divertir com a pontuação em C/C++ programas (incluindo um trigraph bug que poderia defintinely ter me puxando meu cabelo), dê uma olhada no Herb Sutter do GOTW #86 artigo.


Adenda:

Parece que o GCC não processo (e avisar sobre) trigraphs por padrão.Alguns outros compiladores tem opções para desligar trigraph de suporte (como a IBM, por exemplo).A Microsoft começou a apoiar um aviso (C4837) no VS2008 que deve ser explicitamente habilitado (utilizando -Parede ou algo assim).

Outras dicas

A partir de The C++ Programming Language Edição especial, página 829

Os personagens especiais ASCII [, ], {, }, |, e \ Ocupar posições de conjunto de caracteres designadas como alfabéticas pela ISO. Na maioria dos conjuntos nacionais de caracteres da ISO-646 europeia, essas posições são ocupadas por cartas não encontradas no alfabeto inglês.

É fornecido um conjunto de trigraphs para permitir que os caracteres nacionais sejam expressos de maneira portátil usando um conjunto de caracteres mínimo verdadeiramente padrão. Isso pode ser útil para o intercâmbio de programas, mas não facilita a leitura das pessoas. Naturalmente, a solução de longo prazo para esse problema é que os programadores C ++ obtenham equipamentos que suportam seu idioma nativo e bem C ++. Infelizmente, isso parece ser inviável para alguns, e a introdução de novos equipamentos pode ser um processo frustrantemente lento.

As crianças de hoje!:-)

Sim, os aparelhos estrangeiros, como um terminal IBM 3270.3270 tem, se não me engano, não chavetas!Se você quer escrever C em um IBM mini / mainframe, você tinha que use o miserável trigraphs para cada bloco de fronteira.Felizmente, eu só tinha para escrever software em C para emular alguns IBM minicomputador instalações, na verdade, não escreva C software no o System/36.

Olhe ao lado da tecla "P":

keyboard

Hmmm.Difícil dizer.Há um extra botão ao lado de "retorno de carro", e eu poderia tê-lo de trás para frente:talvez fosse o "[" / "]" par que estava faltando.De qualquer forma, este teclado iria causar-lhe dor se você tivesse que escrever C.

Além disso, esses terminais de visualização EBCDIC, da IBM "nativo" mainframe " o conjunto de caracteres não ASCII (obrigado, Pavel Minaev, para o lembrete).

Por outro lado, como o GNU C guia diz:"Você não precisa deste dano cerebral." O compilador gcc deixa esse "recurso" desabilitado por padrão.

Eles são para uso em sistemas que não possuem alguns caracteres em C++conjunto básico de caracteres.Escusado será dizer que tais sistemas são extremamente raros.

Trigraphs foram propostos para remoção em C ++ 0x. Dito isto, ainda parece haver um forte argumento em apoio a eles - veja o documento do comitê C ++ N2910 que discute isso. Aparentemente, o EBCDIC é uma fortaleza importante onde eles são necessários.

Eu vi trigraphs usado no início dos anos 90, para ajudar a converter PL/1 programas a partir de um mainframe para ser executado/compiled/depurado em um PC.

Eles foram dar palpites edição PL/I no PC usando um PL/I para o compilador de C e eles queriam que o código de trabalho, quando se mudou de volta para o mainframe, que não suporta chaves.Eu sugeri que eles poderiam usar macros como

#def BEGIN {    
#def END }  

ou como um amigável de PL/I alternativa.

#def BEGIN ??<
#def END ??>

e se eles realmente queriam começar a fantasia que eles poderiam tentar

#ifdef MAINFRAME
    #def BEGIN ??<
    #def END ??>
#else
    #def BEGIN {    
    #def END }  
#endif

e, em seguida, o programa seria parecido com o que foi escrito em Pascal.Eles apenas me olhou engraçado e não falar para mim para o resto do dia.Eu não acho que eu culpá-los.:)

O que matou o esforço que não o tri-gráficos, foi o sistema de e / s diferenças entre as plataformas.A abertura dos arquivos no PC foi muito diferentes do que o mainframe ele teria introduzido a forma como muitos kludges para manter o mesmo código em execução em ambos.

Alguns teclados europeus não têm (não?) Temos todos os personagens de pontuação que os teclados dos EUA tinham, porque precisavam das chaves para seus personagens alfabéticos incomuns. Por exemplo, (inventando isso), o teclado sueco teria a ring em onde estava a cinta encaracolada.

Para acomodar esses usuários, os trigrafos são uma maneira de entrar na pontuação usando apenas os caracteres ASCII mais comuns.

Principalmente porque o padrão C os apresentou em 1989, quando houve problemas com a presença dos personagens para os quais as trigrafs são mapeadas em algumas máquinas. No momento em que o padrão C ++ foi publicado em 1998, a necessidade de trigráfas não era grande. Eles são uma verruga em C; Eles são tão uma verruga no C ++. Havia a necessidade deles - especialmente fora do mundo de língua inglesa - e é por isso que eles foram adicionados a C.

Eles estão lá principalmente por razões históricas. Atualmente, a maioria dos teclados modernos para a maioria dos idiomas permite o acesso a todos esses personagens, mas isso costumava ser um problema uma vez com alguns teclados europeus. É por isso que as trigrafias foram inventadas.

Se você não sabe para que serve, não deve usá -los.

Ainda é bom estar ciente deles, já que você pode usar acidental e involuntariamente um em seu código.

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