ビジネス課題への解決策(アイディア)と、新たな発想(+α)が見つかるIT情報メディア

Menu
  1. TOP
  2. データ活用
  3. Cのトライグラフ表記

Cのトライグラフ表記

  • LINEで送る
  • このエントリーをはてなブックマークに追加

先日、メインフレームやWindowsなど、異なるプラットフォーム上で動作するソフトウェアのソースを見る機会がありました。
そのソースを見たとき、なんだこれは?
C言語のソースと聞いていたのに、なんだか知らない表記があるけど。。。

それが、トライグラフという表記方法でした。
恥ずかしながら、二十年以上C言語に携わってきましたが、私は初耳でした。

下のソースを見てください。

 

#include <stdio.h>

static char tric[9][4] = {
    { '?', '?', '=', NULL },
    { '?', '?', '(', NULL },
    { '?', '?', '/', NULL },
    { '?', '?', ')', NULL },
    { '?', '?', ''', NULL },
    { '?', '?', '<', NULL },
    { '?', '?', '!', NULL },
    { '?', '?', '>', NULL },
    { '?', '?', '-', NULL }};

static char *tri[9] = {
    "??=",
    "??(",
    "??/",
    "??)",
    "??'",
    "??<",
    "??!",
    "??>",
    "??-" };

void main( int argc, char *argv??(??) );

void main( int argc, char *argv[] ) {

    for ( int i = 0; i < 9; i ++ ) {
        printf( "%s - %sn", tric[i], tri[i] );
    }
}

 

このソースのprintfの出力結果はどうなるでしょうか?
ハイフンの左右文字列は同じでしょ?と思われた方も多いと思います。
いやいや、その前にプロトタイプ宣言がコンパイルエラーでは?と思うかもしれません。
そんなことはなく、コンパイルもできて、実行結果はこうなります。

 

??= - #
??( - [
??/ - 
??) - ]
??' - ^
??< - {
??! - |
??> - }
??- - ~

 
左側は、各文字そのままですが、右側は違う文字になっていますね。
左側が右側の文字をトライグラフで表記したものになります。
これは、ISO646(ASCIIを国際化した規格)の文字のうち、国などで変わる文字以外C言語を表記するためだそうです。

そういえば、このトライグラフを使って書かれたソースを見たのは、メインフレームでした。
メインフレームで使用しているEBCDICコードは、コード体系にもよりますが、C言語で頻繁に使用される"["、"]"(ブラケット)がありません。そのため、トライグラフを使って表記していたようです。
書かれた時代も古かったし、メインフレームで使用していたコンパイラーはSAS-Cというコンパイラーでしたので、半信半疑でVisual C++でコンパイルしてみましたが、ちゃんとコンパイルできました。
なお、コンパイラーやバージョンによっては、オプションで有効/無効の切り替えが必要な場合もあるようです。

処理順位ですが、""内でも変換されることでお分かりのように、コンパイル処理では一番最初に処理されるようです。
そのため、上記ソースのtri[2]には、「」が必要なんです。最初このソース書いたとき、なんでコンパイルエラーなのかと、子一時間悩みました。理由はわかりますよね?先に、「??/」が変換されて、「"",」となり、「」はエスケープ文字として処理されますからね。

突然、C言語で「??」が現れたとき、あせらずにこの記事を思い出してください。

メールマガジンの登録はこちらから
メルマガ登録 お問い合わせ