C ++でのTrigraphシーケンスの目的?


127

C ++ '03 Standard 2.3 / 1によると:

他の処理が行われる前に、以下の3つの文字のシーケンス(「3文字表記シーケンス」)が出現するたびに、表1に示されている単一の文字に置き換えられます。

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

実生活では、これは、文字で置き換えられた3文字表記シーケンスであるため、コードprintf( "What??!\n" );が印刷されることを意味します。What|??!|

私の質問は、トリグラフを使用する目的は何ですか?トリグラフを使用する実用的な利点はありますか?

UPD:回答では、一部のヨーロッパのキーボードには句読点文字がすべて含まれていないため、米国以外のプログラマーは日常生活で3文字表記を使用する必要があると述べられました。

UPD2:Visual Studio 2010では、デフォルトで3文字表記のサポートがオフになっています。


一部の句読点はヨーロッパのキーボードでは到達が困難です(一部のプログラマーはUSレイアウトを使用して入力を速くするほどです)。句読点が完全に欠落しているものを見たことはありません。
peterchen 2009年

2
一部の端末や仮想化では、一部のキャラクターに簡単にアクセスできない場合があります。私の経験では、主な違反者はチルドです。
フランチェスコ

1
DEデッドキーキーボードでこれを入力すると、#はリターンの次のキー、\は "AltGr" + "ß"(0の隣)、^は "^" + "^"(デッドキーのため、1の横) 、[is "AltGr" + "8"、]は "AltGr" + "9"、| は "AltGr" + "<"、{は "AltGr" + "7"、}は "AltGr" + "0"、および〜は "〜" + "〜"です(デッドキーのため、#のすぐ上)。それほど大したことはありません。私の指は、これらの組み合わせを自分で入力するようなものです:-D
nonchip

1
2つのキーボードレイアウトがあり、コンピューターで実行している作業に応じてそれらを切り替えるのは通常のことだと思いました。それは中央ヨーロッパ地域で一般的な方法です。これらのトリグラフを使用するのはかなり気味悪いです。これを標準から削除することに投票します。
VX

回答:


97

この質問(密接に関連するダイグラフについて)には答えがあります。

ISO 646文字セットにはC構文のすべての文字が含まれていないため、文字を処理できないキーボードとディスプレイを備えたシステムがいくつかあります(これらは非常にまれだと思いますが)今日)。

一般に、それらを使用する必要はありませんが、発生した問題について正確に知る必要があります。トリグラフは、 ' ?'文字にエスケープシーケンスがある理由です。

'\?'

したがって、例の問題を回避する方法はいくつかあります。

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

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

ただし、2つの「?」を入力するときは覚えておく必要があります。トリグラフを開始する可能性のある文字(そして私が考えていることは決してありません)。

実際には、トリグラフとダイグラフは、日常的にまったく心配する必要のないものです。しかし、2、3年に1度、それらに関連するバグに遭遇することになるので、それらに注意する必要があります(そして、残りの日を過ごして、それらの存在を呪います)。トライグラフまたはダイグラフに出くわしたときに警告(またはエラー)するようにコンパイラーを構成できれば、意図的に対処する必要があるものがあることがわかります。

そして、完全を期すために、ダイグラフはトークンとして処理されるため、それほど危険ではありません。したがって、文字列リテラル内のダイグラフはダイグラフとして解釈されません。

C / C ++プログラムの句読点のさまざまな楽しみに関するすばらしい教育(間違いなく髪を引っ張ってしまうトリグラフのバグを含む)については、Herb SutterのGOTW#86記事をご覧ください


補遺:

デフォルトでは、GCCは3文字表記を処理しない(および警告する)ようです。他の一部のコンパイラには、トリグラフのサポートをオフにするオプションがあります(IBMなど)。マイクロソフトは、VS2008で(-Wallなどを使用して)明示的に有効にする必要がある警告(C4837)のサポートを開始しました。


Cとの互換性が唯一の理由ですか?最新のC ++プログラムでそれらを満たすことは可能ですか?
キリルV.リヤドビンスキー2009

はい、C ++は3文字表記と2文字表記もサポートしています。
マイケルバー

4
覚えていますが、私が使用した少なくとも1つのコンパイラ(g ++?)では、trigraphやdigraphを変換する前に明示的なコマンドラインオプションが必要です。それ以外の場合、警告は表示されますが、置換は行われません。
KTC、

1
@ Jla3ep-私は個人的にはトライグラフを必要としていませんでしたが、残念ながらコンパイラはそれらを使ってコードを処理するので、(偶発的な使用を避けるために)それらに注意する必要があります。また、別の場所からコードを取得すると、意図的に使用される可能性がありますが、それは非常に珍しいことです。私は20年以上に1回、意図的に使用された3文字表記に出会ったと思います(これはIBMメインフレームのコードでした)。
マイケルバー

1
意外なことをするためにトリグラフがコメントで拡張されたときだけ、それは本当に私の神経質になります。
ジョシュア

23

今日の子供たち!:-)

はい、IBM 3270端末などの外部機器。3270には、覚えていると思いますが、中括弧はありません。IBM mini /メインフレームでCを記述したい場合は、すべてのブロック境界に難解な3文字表記使用する必要がありました。幸いにも、IBMのミニコンピューター機能をエミュレートするために、Cでソフトウェアを作成するだけで済みました。実際は、システム/ 36でCソフトウェア作成する必要はありませんでした。

「P」キーの横を見てください。

キーボード

うーん。わかりにくい。「キャリッジリターン」の隣に追加のボタンがあり、私はそれを逆方向に持っているかもしれません:欠けていたのは「[」/「]」のペアだったのかもしれません。とにかく、Cを書く必要がある場合、このキーボードはあなたを悲しませます。

また、これらの端末は、ASCIIではなくIBMの「ネイティブ」メインフレーム文字セットであるEBCDICを表示します(リマインダーとしてPavel Minaevに感謝)。

一方、GNU Cガイドが言うように:「あなたはこの脳の損傷を必要としません。」gccコンパイラーは、この「機能」をデフォルトで無効のままにします。


1
キーボードにはリセットボタンがあります。すごい!最初に私の注意を引いた奇妙な。
l46kok 2013

10
EBCDICマシンでC ++ 17を使用したい人は誰でも、壊死症のために投獄されるべきです。
SF。

プラットフォームは何の文字がない場合を除き、すべての ISO646のもの以外に、トリグラフで行うことができるすべてのものは、すべての実装は、バックスラッシュまたは他のAとCの文字セットではなく、任意の文字のいずれかを定義することを要求することによって行うことができませんでした「メタ」文字、標準のバックスラッシュへのすべての参照を「メタ」に置き換え、ISO-646にないC文字セットのメンバーにバックスラッシュ/メタエスケープを追加しますか?
supercat '11 / 11/16

22

以下からのThe C++ Programming Language特別版、ページ829

ASCII特殊文字[]{}|、および\ISOによってアルファベットとして指定された文字セットの位置を占めます。ほとんどのヨーロッパの国別ISO-646文字セットでは、これらの位置は英語のアルファベットにはない文字で占められています。

真に標準的な最小文字セットを使用して国別文字を移植可能な方法で表現できるようにするために、トリグラフのセットが提供されています。これはプログラムの交換には役立ちますが、人々がプログラムを読みやすくなるわけではありません。当然、この問題の長期的な解決策は、C ++プログラマーがネイティブ言語とC ++の両方を適切にサポートする機器を入手することです。残念ながら、これは一部の人にとって実行不可能であるように見え、新しい機器の導入はイライラするほど遅いプロセスになる可能性があります。


7
「新しい機器の導入は、イライラするほど遅いプロセスになる可能性があります」。特に、プログラミング言語機能を標準化する迅速で痛みのないプロセスと比較してください。
jforberg 14

4
これがキーボードレイアウトの行き詰まりである場合、たとえばタイピング用の3文字表記がないことはおかしいです`。これは、イタリア語や他のいくつかのキーボードレイアウトにはありません
badp

15

これらは、C ++の基本的な文字セットの一部の文字が不足しているシステムで使用するためのものです。言うまでもなく、そのようなシステムは非常にまれです。


2
それは私が実際にそれらを使用することは決してないという意味ですか?
キリルV.リヤドビンスキー2009

1
どこの国にお住まいですか?すべての言語のすべてのキーボードに必要なキーがあるわけではありません。
David Thornley、

2
はい。ただし、文字列リテラルなどで検索したときに予期しない結果が発生した場合に備えて、その存在に注意する必要がある場合があります。
CBベイリー

4
@David Thornley:最新のシステムのほとんどは、C ++の基本的な文字をすべてサポートしています。これらの文字が従来の場所にない場合や、タイプするために修飾シーケンスを必要とする場合でも同様です。トライグラフは、システムの文字セットで実際に文字を表現できないシステムのソースコードで維持する必要があるだけでした。私はまだそのようなシステムが非常にまれであることを維持します。
CBベイリー

9

トライグラフは、C ++ 0xでの削除が提案されています。そうは言っても、それらを支持する強い議論があるようです- これについて議論しているC ++委員会のペーパーN2910を参照してください。どうやら、EBCDICは必要とされる主要な拠点の1つです。


はい、その「外国語」!:-)
ロボプログ2009

彼らは「顧客フィードバックの内部調査の結果」以外はあまり言いませんが、まあ。EBCDICがまだ広く使用されていること(およびこれらのシステムがC ++ 0xコンパイラーの使用を想定していること)に
驚いています

5

PL / 1プログラムをメインフレームからPCで実行/コンパイル/デバッグできるように変換するために90年代初頭に使用された3文字表記を見てきました。

彼らは、PL / I to Cコンパイラを使用してPCでPL / Iを編集することに手を出しており、中括弧をサポートしていないメインフレームに戻ったときにコードが機能することを望んでいました。私は彼らが次のようなマクロを使用できることを提案しました

#def BEGIN {    
#def END }  

またはより使いやすいPL / Iの代替として

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

そして、彼らが本当に空想を得たいと思ったら、彼らは試すことができます

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

プログラムはPascalで書かれたように見えます。彼らは私をおかしく見ただけで、その日の残りの時間は私に話しかけませんでした。私は彼らを責めるとは思わない。:)

トライグラフではなく、努力を殺したのは、プラットフォーム間のIOシステムの違いでした。PCでファイルを開くのはメインフレームとは大きく異なり、両方で同じコードを実行し続けるには余りにも多くの手間がかかりました。


PL / 1 = IBMのバージョンのC(多かれ少なかれ)。私のコメントを参照してください:IBM端末には '{' / '}'キーがありません:-(これらのいずれかでC [++]を書くのは難しいです。それ以外の場合
Roboprog

3

主に、C標準がそれらを導入したのは1989年に、トリグラフが一部のマシンでマップされる文字の存在に問題があったためです。1998年にC ++標準が発表されたときには、3文字表記の必要性はそれほど高くありませんでした。Cのいぼです。それらはC ++と同様にいぼです。彼らの必要性がありました-特に英語圏以外では-それが彼らがCに追加された理由です。


1
IBMは英語を話さないといつも思っていました:-)
Roboprog

3

ヨーロッパの一部のキーボードには、USキーボードにある句読文字がすべて含まれていない(含まれていなかった)ため、珍しいアルファベット文字のキーが必要だったためです。たとえば、(これを構成する)たとえば、スウェーデン語のキーボードには、中括弧があった場所にAリングがあります。

それらのユーザーに対応するために、トリグラフは、最も一般的なASCII文字のみを使用して句読点を入力する方法です。


4
トライグラフは、実際にはデータ入力に関するものではなく(コードをかなり読みにくくします)、実際に必要な文字がないシステムに関するものです。システムが文字を記録および表示できる場合(たとえ3文字表記のようなキーシーケンスを入力する必要がある場合でも)、3文字表記のシーケンスをソースに保持しない方がはるかに簡単です。
CBベイリー

2

彼らは主に歴史的な理由でそこにあります。今日では、ほとんどの言語のほとんどの最新のキーボードでこれらすべての文字にアクセスできますが、これはかつて一部のヨーロッパのキーボードでは問題でした。これが、トリグラフが発明された理由です。

それらの用途がわからない場合は使用しないでください。

ただし、コードで誤って、または意図せずに使用してしまう可能性があるため、これらを認識することは依然として良いことです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.