先日、メインフレームや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言語で「??」が現れたとき、あせらずにこの記事を思い出してください。
Rankingランキング
New arrival新着
Keywordキーワード