Pregunta

De acuerdo con C ++ '03 Standard 2.3 / 1:

  

Antes de que tenga lugar cualquier otro procesamiento, cada aparición de una de las siguientes secuencias de tres caracteres (& # 8220; secuencias de trigraph & # 8221;) se reemplaza por el carácter único indicado en la Tabla 1.

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

En la vida real, eso significa que el código printf (" What ??! \ n "); dará como resultado la impresión de What | porque ??! es una secuencia trigráfica que se reemplaza con el carácter | .

Mi pregunta es ¿con qué propósito usar trigrafos? ¿Hay alguna ventaja práctica de usar trigráficos?

UPD : en las respuestas se mencionó que algunos teclados europeos no tienen todos los caracteres de puntuación, por lo que los programadores no estadounidenses tienen que usar trigráficos en la vida cotidiana.

UPD2 : Visual Studio 2010 tiene el soporte de trigraph desactivado de forma predeterminada.

¿Fue útil?

Solución

Esta pregunta (sobre los dígrafos estrechamente relacionados) tiene la respuesta.

Se reduce al hecho de que el conjunto de caracteres ISO 646 no tiene todos los caracteres de la sintaxis C, por lo que hay algunos sistemas con teclados y pantallas que no pueden manejar los caracteres (aunque imagino que estos son bastante raros hoy en día).

En general, no necesita usarlos, pero necesita saber acerca de ellos para saber exactamente el problema que encontró. Los trígrafos son la razón por la cual el carácter '? ' tiene una secuencia de escape:

'\?'

Entonces, un par de formas en que puede evitar su problema de ejemplo son:

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

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

Pero tienes que recordar cuando estás escribiendo los dos '?' personajes en los que podrías comenzar un trigraph (y ciertamente nunca es algo en lo que esté pensando).

En la práctica, los trigraphs y digraphs son algo de lo que no me preocupo en absoluto en el día a día. Pero debes estar al tanto de ellos porque una vez cada dos años te encontrarás con un error relacionado con ellos (y pasarás el resto del día maldiciendo su existencia). Sería bueno si los compiladores pudieran configurarse para advertir (o error) cuando se trata de un trígrafo o un dígrafo, por lo que podría saber que tengo algo con lo que debo tratar a sabiendas.

Y solo para completar, los dígrafos son mucho menos peligrosos ya que se procesan como tokens, por lo que un dígrafo dentro de un literal de cadena no se interpretará como un dígrafo.

Para una buena educación sobre diversas diversiones con puntuación en programas C / C ++ (incluido un error de trigraph que definitivamente me haría arrancarme el pelo), eche un vistazo a Artículo GOTW # 86 de Herb Sutter .


Anexo:

Parece que GCC no procesará (y advertirá sobre) los trigrafos de forma predeterminada. Algunos otros compiladores tienen opciones para desactivar el soporte de trigraph (por ejemplo, de IBM). Microsoft comenzó a admitir una advertencia (C4837) en VS2008 que debe habilitarse explícitamente (usando -Wall o algo así).

Otros consejos

De El lenguaje de programación C ++ Edición especial, página 829

  

Los caracteres especiales ASCII [, ] , {, } , | y \ ocupan las posiciones del juego de caracteres designadas como alfabéticas por ISO. En la mayoría de los juegos de caracteres ISO-646 nacionales europeos, estas posiciones están ocupadas por letras que no se encuentran en el alfabeto inglés.

     

Se proporciona un conjunto de trigrafos para permitir que los caracteres nacionales se expresen de forma portátil utilizando un conjunto de caracteres mínimos verdaderamente estándar. Esto puede ser útil para el intercambio de programas, pero no facilita que las personas lean programas. Naturalmente, la solución a largo plazo a este problema es que los programadores de C ++ obtengan equipos que admitan tanto su idioma nativo como C ++. Desafortunadamente, esto parece inviable para algunos, y la introducción de nuevos equipos puede ser un proceso frustrantemente lento.

¡Niños hoy! :-)

Sí, equipo extraño, como un terminal IBM 3270. El 3270 no tiene, si mal no recuerdo, llaves. Si deseaba escribir C en un mini / mainframe de IBM, tenía que usar los miserables trigrafos para cada límite de bloque. Afortunadamente, solo tuve que escribir software en C para emular algunas instalaciones de minicomputadora de IBM, en realidad no escribir software C en el Sistema / 36.

Mira al lado de " P " clave:

 keyboard

Hmmm. Difícil de decir. Hay un botón adicional al lado de '' retorno de carro '', y podría tenerlo al revés: tal vez fue el '' ['' / "] " par que faltaba. En cualquier caso, este teclado te causaría dolor si tuvieras que escribir C.

Además, estos terminales muestran EBCDIC, el "nativo" de IBM conjunto de caracteres de mainframe, no ASCII (gracias, Pavel Minaev, por el recordatorio).

Por otro lado, como dice la guía GNU C: "No necesitas este daño cerebral". El compilador gcc deja esta " característica " deshabilitado por defecto.

Se usan en sistemas que carecen de algunos de los caracteres del conjunto de caracteres básico de C ++. No hace falta decir que tales sistemas son extremadamente raros.

Se han propuesto trígrafos para su eliminación en C ++ 0x. Dicho esto, todavía parece haber un fuerte argumento en apoyo de ellos: consulte el documento del comité de C ++ N2910 que analiza esto. Aparentemente, EBCDIC es una fortaleza importante donde se necesitan.

He visto los trigrafos utilizados a principios de los años 90 para ayudar a convertir programas PL / 1 de un mainframe para ejecutar / compilar / depurar en una PC.

Estaban incursionando en la edición de PL / I en la PC usando un compilador de PL / I a C y querían que el código funcionara cuando volvieran a la unidad central que no admitía llaves. Sugerí que podrían usar macros como

#def BEGIN {    
#def END }  

o como una alternativa PL / I más amigable

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

y si realmente quisieran ponerse elegantes, podrían intentarlo

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

y luego el programa se vería como si estuviera escrito en Pascal. Simplemente me miraron divertido y no me hablaron por el resto del día. No creo que los culpe. :)

Lo que mató el esfuerzo, no los tres gráficos, fueron las diferencias del sistema IO entre las plataformas. Abrir archivos en la PC era tan diferente al mainframe que habría introducido demasiados errores para mantener el mismo código ejecutándose en ambos.

Algunos teclados europeos no tienen (¿no?) todos los caracteres de puntuación que tenían los teclados estadounidenses, porque necesitaban las teclas para sus caracteres alfabéticos inusuales. Entonces, por ejemplo (inventando esto), el teclado sueco tendría un anillo A donde estaba la llave.

Para acomodar a esos usuarios, los trigrafos son una forma de ingresar puntuación usando solo los caracteres ASCII más comunes.

Principalmente porque el estándar C los introdujo en 1989, cuando había problemas con la presencia de los caracteres a los que se asignan los trigrafos en algunas máquinas. Para cuando se publicó el estándar C ++ en 1998, la necesidad de trigrafos no era grande. Son una verruga en C; son igual de verrugas en C ++. Era necesario para ellos, especialmente fuera del mundo de habla inglesa, por lo que se agregaron a C.

Están allí principalmente por razones históricas. Hoy en día, la mayoría de los teclados modernos para la mayoría de los idiomas permiten el acceso a todos esos caracteres, pero esto solía ser un problema una vez con algunos teclados europeos. Por eso se inventaron los trigrafos.

Si no sabes para qué sirven, no deberías usarlos.

Sin embargo, es bueno estar al tanto de ellos, ya que puede usar uno accidental y accidentalmente en su código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top