2009-11-03 6 views
6

habe ich ein neues Projekt mit dem folgende Codesegment:Unbekanntes Meta-Zeichen in C/C++ - String-Literal?

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

in folgenden Ausgabe führt:

(merkwürdige]

So übersetzt '??)' -> ']'

Debuggen zeigt, dass mein Char * String-Literal ist eigentlich dieser Wert und es ist keine Stream-Übersetzung. Dies ist offensichtlich keine Meta-Zeichenfolge, die ich je gesehen habe. Eine Art von Unicode oder eine breite Char-Sequenz vielleicht? Ich glaube aber nicht ... Ich habe versucht, alle zugehörigen Projekteinstellungen ohne Erfolg zu deaktivieren.

Hat jemand eine Erklärung?

  • Suche: 'Fragezeichen, Fragezeichen, in der Nähe Klammer' c C++ Stringliteral
+0

Diese Frage könnte Ihnen helfen: http://stackoverflow.com/questions/1234582/purpose-of-trigraph-sequences-in-c –

+0

danke ... Ich habe die Suche am Ende meiner Post in den Hoffnungen hinzugefügt Diese zukünftigen Suchvorgänge würden dem doppelten Fragezeichenkonstrukt entsprechen. Diese Design-Entscheidung (indem sie als Standard aktiviert wird) ist in einem Wort: "verrückt". Belassen Sie Trigraphen für das OS/UI, das ich sage. – Marius

+1

Speziell für die Fälle, in denen das OS/UI nicht ausreichend war, wurden spezielle Trigramme hinzugefügt. Denken Sie daran, dass C aus einer Zeit stammt, als die Benutzeroberfläche eine 9600-Baud-Terminal-Verbindung war und ASCII weit davon entfernt war, universell zu sein. – caf

Antwort

18

Was Sie sehen eine trigraph genannt wird.

In schriftlicher Sprache von Erwachsenen ist ein Fragezeichen für jede Situation ausreichend. Benutze nicht mehr als eins auf einmal und du wirst das nie wieder sehen.

GCC ignoriert Trigraphen standardmäßig, weil kaum jemand sie absichtlich verwendet. Aktivieren Sie sie mit der Option -trigraph, oder weisen Sie den Compiler an, Sie mit der Option -Wtrigraphs darüber zu warnen.

Visual C++ 2010 deaktiviert sie auch standardmäßig und bietet /Zc:trigraphs, um sie zu aktivieren. Ich kann nichts über Möglichkeiten finden, sie in früheren Versionen zu aktivieren oder zu deaktivieren.

+0

+1, aber es ist eigentlich ein Trigraph http://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C. –

+0

Sie kommentiert schnell. Ich habe es behoben, als ich bemerkte, dass dort wirklich drei Charaktere waren. Vielen Dank. –

+8

Ist die beleidigende Andeutung, dass Marius nicht erwachsen ist, wirklich notwendig? Ich bin dabei, die Abstimmung auf die Annahme zu beschränken, dass es in guter Stimmung gemeint war, aber es ist wirklich ziemlich gering und völlig unnötig. –

4

Das ist trigraph Unterstützung. Sie können trigraph Interpretation verhindern, indem sie eines der Zeichen zu entkommen:

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

einfache Möglichkeit, die trigraph Überraschung zu vermeiden: split ein „??"Stringliteral in zwei:

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

bearbeiten
gcc hat eine Option über trigraphs zu warnen: -Wtrigraphs (aktiviert mit -Wall auch)
Ende bearbeiten

Zitate aus dem Standard-

 
    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. 
2

Wie schon mehrmals erwähnt, werden Sie von einem Trigraph gebissen. Sehen Sie diese vorherige SO Frage für weitere Informationen:

Sie das Problem beheben kann, die unter Verwendung '\?' Escape-Sequenz für das '?' Charakter:

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

In der Tat ist dies der Grund für diese Escape-Sequenz, die etwas geheimnisvoll ist, wenn Sie keine Kenntnis von diesen verdammten trigraphs sind.

+0

Danke für die Antwort ... aufgrund der Natur dieses Fehlers ist es unmöglich, nach einer Antwort zu suchen, es sei denn, man weiß, dass es ein Trigraph ist. Das Problem mit der Reparatur ist, dass ich generierte C von einem Lex/Yacc-Parser-Generator verwende. Ich habe meine eigenen Trigraphs auf meinem Mac verwendet und erstellt, und ich habe das Gefühl, dass das Betriebssystem dafür geeignet ist, Trigraph-Tastatursequenzen und nicht den Compiler zu handhaben. In der Tat nur in VS 2010 werden sie dieses Standardverhalten ändern. – Marius

+0

Ja - ich kann mir vorstellen, dass die Suche nach Hilfe dazu, ohne bereits zu wissen, was ein Trigraph ist, ein ernstes Henne-und-Ei-Problem darstellt. Wenn Sie die lex/yacc-Ausgabe nicht ändern können und einen Compiler verwenden müssen, der Trigraphs (VS2010 oder GCC) nicht ignoriert, dann denke ich, dass Sie die lex/tacc-Ausgabe über einen Filter ausführen müssen Ändere Trigraphen in harmlose Nicht-Trigraphs. –

+0

Wenn yacc wirklich falsches C ausgibt ("inkorrekt", weil es die angegebene Grammatik nicht analysiert, wenn diese Grammatik aufeinanderfolgende Fragezeichen enthält), ist das ziemlich schlecht. OK, also ist es nur falsch, weil C falsch ist, aber wenn Sie Code-Generierungs-Tools schreiben, denke ich, dass Sie es auf sich nehmen, sowohl mit Features als auch mit Fehlfunktionen Ihrer Zielsprache umzugehen. Aber wenn es nur schief geht, weil ein Trigraph in einer yacc-Aktion erscheint, ist das der Fehler des Benutzers, es dort zu platzieren. –

1

Während zu versuchen, Cross-kompilieren auf GCC es meine Sequenz aufgenommen als trigraph:

Also alles, was ich jetzt tun müssen, ist herauszufinden, wie dies standardmäßig in Projekten zu deaktivieren, da ich nur sehen kann, es zu schaffen Probleme für mich. (Ich benutze sowieso ein US-Tastaturlayout)

Das Standardverhalten auf GCC ist zu ignorieren, aber eine Warnung geben, die viel vernünftiger ist und ist in der Tat, was Visual Studio 2010 als den Standard übernehmen wird, soweit ich weiß .