C++Builder とトライグラフ

# はじめに

C/C++ には**トライグラフ (3 文字表記)** というものがあります。環境によって表現できない文字の代わりに 3 文字のシーケンスでその文字を表すもので、規格としては `ANSI C (ANSI X3.159-1989)` で盛り込まれています。

 - [トライグラフ (Wikipedia)](https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%82%A4%E3%82%B0%E3%83%A9%E3%83%95)
 - [ISO/IEC 646 (Wikipedia)](https://ja.wikipedia.org/wiki/ISO/IEC_646)
 - [ANSI C (Wikipedia)](https://ja.wikipedia.org/wiki/ANSI_C)

| 文字 | トライグラフ |
|:---:|:---:|
|#|??=|
|[|??(|
|\\ [^1]|??/|
|]|??)|
|^|??'|
|{|??<|
|｜ [^2]|??!|
|}|??>|
|~|??-|

コンパイラでトライグラフに対応しようとするとコンパイル処理速度が低下するため、Borland 製の C/C++ コンパイラ (Turbo C++ / Borland C++ / C++ Builder) には TRIGRAPH.EXE というフィルタが付属し、これでトライグラフを前処理するようになっていました。

TRIGRAPH.EXE は [Turbo C++ 1.01](https://cc.embarcadero.com/item/26014) や [Borland C++ 5.5](http://forms.embarcadero.com/forms/jp_cpp_download_reg) に含まれている事が確認できます。最近の C++Builder や [C++ Compiler](https://www.embarcadero.com/jp/free-tools/ccompiler) には含まれていないようです。

| 通称 | 規格 | JIS |
|:---|:---|:---|
| ANSI C / C89 | ANSI X3.159-1989 |   |
| C90 | ISO/IEC 9899: 1990 | JIS X3010:1993 |
| C95 | ISO/IEC 9899/AMD1:1995 | JIS X 3010:1993/AMENDMENT 1:1996 |
| C99 | ISO/IEC 9899:1999 | JIS X 3010:2003 |

Turbo C は ANSI C (ドラフト) と K&R に準拠している事になっていますが、最終バージョンの 2.0 でも発売が 1988 年なため、トライグラフには対応していないようです。

 - [TRIGRAPH (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/TRIGRAPH)
 - [Borland C++ Compiler 5.5 - FAQ (Embarcadero)](http://edn.embarcadero.com/article/33545#11QBCC%E3%81%AB%E3%81%AF%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9BCC%E3%82%84%E3%83%AA%E3%83%B3%E3%82%ABILINK%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9BRCBRCC%E4%BB%A5%E5%A4%96%E3%81%AB%E3%81%A9%E3%82%93%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB%E3%81%8C%E5%90%AB%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B)
 - [Turbo C++ 1.01 (Embarcadero)](https://cc.embarcadero.com/item/26014)
 - [Borland C++ 5.5 (Embarcadero)](http://forms.embarcadero.com/forms/jp_cpp_download_reg)
 - [C++ Compiler (Embarcadero)](https://www.embarcadero.com/jp/free-tools/ccompiler)

## Pascal のダイグラフ

なお、Pascal では似たような問題を以下の **ダイグラフ (2 文字表記)** で回避しています。規格としては `ISO 7185:1983` で盛り込まれているようです。

| 文字 | ダイグラフ |
|:---:|:---:|
|{|(*|
|}|*)|
|[|(.|
|]|.)|

 - [ダイグラフ (Wikipedia)](https://ja.wikipedia.org/wiki/%E3%83%80%E3%82%A4%E3%82%B0%E3%83%A9%E3%83%95)
 - [CDC display code (Wikipedia:en)](https://en.wikipedia.org/wiki/CDC_display_code)
 - [ISO/IEC 7185 :1990 Pascal (pascal-central.com)](https://pascal-central.com/docs/iso7185.pdf)
 - [JIS X 3008: 1994 プログラム言語 Pascal (kikakurui.com)](http://kikakurui.com/x3/X3008-1994-01.html) - ISO/IEC 7185: 1990 相当の JIS 規格

例えば Apple II のキーボードには { } [ ] がありません (画像は [Wikipedia](https://ja.wikipedia.org/wiki/Apple_II) より)。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/6d5716f1-949c-b842-4840-6cff5fed870e.png)

IBM 5100 には { } がありません (画像は [Wikipedia](https://ja.wikipedia.org/wiki/IBM_5100) より)。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/1d4fb2d9-2739-8924-74c7-4786ad7c9fa7.png)
Pascal のダイグラフはこのようなキーボードで  { } [ ] を代替するためのシーケンスです。これは現行の Delphi でも扱う事ができます。

## C/C++ (C95 以降) のダイグラフ

`C95 (ISO/IEC 9899/AMD1:1995)` 以降にはダイグラフもあります。

| 文字 | ダイグラフ |
|:---:|:---:|
|[|<:|
|]|:>|
|{|<%|
|}|%>|
|#|%:|
|##|%:%:|

 - [Digraphs and trigraphs (Wikipedia: en)](https://en.wikipedia.org/wiki/Digraphs_and_trigraphs)
 - [JIS X 3010: 2003 プログラム言語 C (kikakurui.com)](http://kikakurui.com/x3/X3010-2003-01.html) - C99 相当の JIS 規格

# さて...

**トライグラフは C++17 で廃止**となっています。そうなると、C++Builder 最新版 である 10.3 Rio では割と愉快 (?) な事になるのです。

## 検証

以下のような Hello,world. アプリケーションがあったとします。

```cpp:hello.cpp
#pragma hdrstop
#pragma argsused

#ifdef _WIN32
#include <tchar.h>
#else
  typedef char _TCHAR;
  #define _tmain main
#endif

#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
	std::cout << "Hello, World!" << std::endl;
	return 0;
}
```

これをトライグラフで変換するとこうなります。

```cpp:hello.cpp
??=pragma hdrstop
??=pragma argsused

??=ifdef _WIN32
??=include <tchar.h>
??=else
  typedef char _TCHAR;
  ??=define _tmain main
??=endif

??=include <iostream>

int _tmain(int argc, _TCHAR* argv??(??))
??<
	std::cout << "Hello, World!" << std::endl;
	return 0;
??>
```

?? が多いですけど文字化けじゃないです。

### BCC32C でコンパイル

BCC32C というのは新しい clang ベースのコンパイラです。10.3 Rio からはこちらがデフォルトのコンパイラになっているようですね。[プロジェクト | オプション... ] で**従来の Borland コンパイラを使用**のチェックを外せば BCC32C が使われます (10.3 Rio では最初から外れています)。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/85164689-4901-8c29-0182-bcab5eab71f8.png)
ちなみに BCC32X というコンパイラもあります。こちらも BCC32C 同様 Windows 32bit アプリ用コンパイラなのですが、違いはコマンドラインオプションの記述方法だけです。クロスプラットフォーム用の他のコンパイラとオプションを合わせたのが BCC32X で、従来の BCC32 準拠なのが BCC32C です。IDE からコンパイルされる場合には BCC32C が使われます。

```
プロジェクトの依存関係を確認中...
Project1.cbproj をビルド中 (Debug, Win32)
bcc32c の "Project1PCH1.h" コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\bcc32c.exe -cc1 -D _DEBUG -output-dir .\Win32\Debug -I 
  C:\Users\OWNER\Documents\Embarcadero\Studio\Projects -isystem "c:\program files (x86)\embarcadero\studio\20.0\include" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\crtl" -isystem 
  "c:\program files (x86)\embarcadero\studio\20.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\rtl" 
  -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\vcl" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\windows\fmx" -isystem C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -isystem 
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -debug-info-kind=standalone -fborland-extensions -nobuiltininc -nostdsysteminc -triple 
  i686-pc-windows-omf -emit-pch -mrelocation-model static -masm-verbose -ffunction-sections -fexceptions -fcxx-exceptions -fseh -mdisable-fp-elim 
  -fno-spell-checking -fno-use-cxa-atexit -fno-threadsafe-statics -x c++ -std=c++17 -O0 -fmath-errno -tC -tM -o .\Win32\Debug\Project1PCH1.pch 
  --auto-dependency-output Project1PCH1.h 
bcc32c の "File1.cpp" コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\bcc32c.exe -cc1 -D _DEBUG -output-dir .\Win32\Debug -I 
  C:\Users\OWNER\Documents\Embarcadero\Studio\Projects -isystem "c:\program files (x86)\embarcadero\studio\20.0\include" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\crtl" -isystem 
  "c:\program files (x86)\embarcadero\studio\20.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\rtl" 
  -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\vcl" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\windows\fmx" -isystem C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -isystem 
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -debug-info-kind=standalone -fborland-extensions -nobuiltininc -nostdsysteminc -triple 
  i686-pc-windows-omf -emit-obj -mrelocation-model static -masm-verbose -ffunction-sections -fexceptions -fcxx-exceptions -fseh -mdisable-fp-elim 
  -fno-spell-checking -fno-use-cxa-atexit -fno-threadsafe-statics -main-file-name File1.cpp -x c++ -std=c++17 -O0 -fmath-errno -tC -tM -o 
  .\Win32\Debug\File1.obj --auto-dependency-output -MT .\Win32\Debug\File1.obj -include-pch .\Win32\Debug\Project1PCH1.pch File1.cpp 
[bcc32c 警告] File1.cpp(1): trigraph ignored
[bcc32c エラー] File1.cpp(1): expected unqualified-id
[bcc32c 警告] File1.cpp(2): trigraph ignored
[bcc32c 警告] File1.cpp(4): trigraph ignored
[bcc32c 警告] File1.cpp(5): trigraph ignored
[bcc32c 警告] File1.cpp(6): trigraph ignored
[bcc32c 警告] File1.cpp(8): trigraph ignored
[bcc32c エラー] File1.cpp(8): expected unqualified-id
[bcc32c 警告] File1.cpp(9): trigraph ignored
[bcc32c 警告] File1.cpp(11): trigraph ignored
[bcc32c 警告] File1.cpp(13): trigraph ignored
[bcc32c 警告] File1.cpp(13): trigraph ignored
[bcc32c 警告] File1.cpp(14): trigraph ignored
[bcc32c エラー] File1.cpp(16): expected unqualified-id
[bcc32c 警告] File1.cpp(17): trigraph ignored
[bcc32c エラー] File1.cpp(17): expected unqualified-id
失敗
経過時間: 00:00:00.4
```

結果は...コンパイルエラーになりました。


### BCC32 でコンパイル

BCC32 は従来からある Windows 32 bit アプリケーション向けのコンパイラですが、10.3 Rio からはデフォルトでは使われなくなっています。このコンパイラを使うためには [プロジェクト | オプション... ] で**従来の Borland コンパイラを使用**にチェックを入れる必要があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/422fe410-a7ed-eeb3-df17-d8be2cdc9f87.png)

コンパイルの結果は...

```
プロジェクトの依存関係を確認中...
Project1.cbproj をビルド中 (Debug, Win32)
bcc32 の "File1.cpp" コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\bcc32.exe -D_DEBUG -n.\Win32\Debug -I"c:\program files (x86)\embarcadero\studio\20.0\include";
  "c:\program files (x86)\embarcadero\studio\20.0\include\dinkumware";"c:\program files (x86)\embarcadero\studio\20.0\include\windows\crtl";"c:\program 
  files (x86)\embarcadero\studio\20.0\include\windows\sdk";"c:\program files (x86)\embarcadero\studio\20.0\include\windows\rtl";"c:\program files 
  (x86)\embarcadero\studio\20.0\include\windows\vcl";"c:\program files (x86)\embarcadero\studio\20.0\include\windows\fmx";
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32;C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win32 -y -Q -k -r- -c -tC -tM -C8 
  -o.\Win32\Debug\File1.obj -w-par -Od -v -vi- -H=.\Win32\Debug\Project1.pch -H File1.cpp 
[bcc32 エラー] File1.cpp(1): E2040 宣言が正しく終了していない
[bcc32 エラー] File1.cpp(8): E2040 宣言が正しく終了していない
[bcc32 エラー] File1.cpp(16): E2040 宣言が正しく終了していない
[bcc32 エラー] File1.cpp(17): E2040 宣言が正しく終了していない
失敗
経過時間: 00:00:00.3
```

まぁ、コンパイルエラーになりますよね。TRIGRAPH.EXE でトライグラフを除去する前提だったのですから。

### BCC64 でコンパイル

今度はターゲットプラットフォームに Windows 64 ビットを追加してコンパイルしてみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/708cecca-fb0f-460d-c52b-fec78e8c5924.png)
64 bit Windows アプリ向けコンパイラには "従来のコンパイラ" は存在しないので、64 bit ビルドにすればコンパイラとして BCC64 が使われます。　 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/333b3d3a-c1dc-3e3d-990f-4004f31104b1.png)
さて...

```
プロジェクトの依存関係を確認中...
Project1.cbproj をビルド中 (Debug, Win64)
bcc64 の "Project1PCH1.h" コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\bcc64.exe -cc1 -D _DEBUG -output-dir .\Win64\Debug -I 
  C:\Users\OWNER\Documents\Embarcadero\Studio\Projects -isystem "c:\program files (x86)\embarcadero\studio\20.0\include" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\crtl" -isystem 
  "c:\program files (x86)\embarcadero\studio\20.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\rtl" 
  -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\vcl" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\windows\fmx" -isystem C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64 -isystem 
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64 -debug-info-kind=standalone -fborland-extensions -nobuiltininc -nostdsysteminc -triple 
  x86_64-pc-win32-elf -emit-pch -fexceptions -fcxx-exceptions -fseh -munwind-tables -fno-spell-checking -fno-use-cxa-atexit -x c++ -std=c++11 -O0 
  -fmath-errno -tC -tM -o .\Win64\Debug\Project1PCH1.pch Project1PCH1.h 
bcc64 の "File1.cpp" コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\bcc64.exe -cc1 -D _DEBUG -output-dir .\Win64\Debug -I 
  C:\Users\OWNER\Documents\Embarcadero\Studio\Projects -isystem "c:\program files (x86)\embarcadero\studio\20.0\include" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\crtl" -isystem 
  "c:\program files (x86)\embarcadero\studio\20.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\rtl" 
  -isystem "c:\program files (x86)\embarcadero\studio\20.0\include\windows\vcl" -isystem "c:\program files 
  (x86)\embarcadero\studio\20.0\include\windows\fmx" -isystem C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64 -isystem 
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\hpp\Win64 -debug-info-kind=standalone -fborland-extensions -nobuiltininc -nostdsysteminc -triple 
  x86_64-pc-win32-elf -emit-obj -fexceptions -fcxx-exceptions -fseh -munwind-tables -fno-spell-checking -fno-use-cxa-atexit -main-file-name File1.cpp 
  -x c++ -std=c++11 -O0 -fmath-errno -tC -tM -o .\Win64\Debug\File1.o -dependency-file .\Win64\Debug\File1.d -MT .\Win64\Debug\File1.o -sys-header-deps 
  -include-pch .\Win64\Debug\Project1PCH1.pch File1.cpp 
[bcc64 警告] File1.cpp(1): 3 文字表記が '#' 文字に変換されました
[bcc64 警告] File1.cpp(2): 3 文字表記が '#' 文字に変換されました
[bcc64 警告] File1.cpp(4): 3 文字表記が '#' 文字に変換されました
[bcc64 警告] File1.cpp(5): 3 文字表記が '#' 文字に変換されました
[bcc64 警告] File1.cpp(6): 3 文字表記が '#' 文字に変換されました
[bcc64 警告] File1.cpp(11): 3 文字表記が '#' 文字に変換されました
[bcc64 警告] File1.cpp(13): 3 文字表記が '[' 文字に変換されました
[bcc64 警告] File1.cpp(13): 3 文字表記が ']' 文字に変換されました
[bcc64 警告] File1.cpp(14): 3 文字表記が '{' 文字に変換されました
[bcc64 警告] File1.cpp(17): 3 文字表記が '}' 文字に変換されました
brcc32 の "Project1.vrc" コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res 
ilink64 コマンド ライン
  c:\program files (x86)\embarcadero\studio\20.0\bin\ilink64.exe -G8 -L.\Win64\Debug;"c:\program files (x86)\embarcadero\studio\20.0\lib\Win64\debug";
  "c:\program files (x86)\embarcadero\studio\20.0\lib\win64\release";"c:\program files (x86)\embarcadero\studio\20.0\lib\win64\release\psdk";
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;C:\Users\Public\Documents\Embarcadero\Studio\20.0\DCP\Win64\Debug;
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64 -j.\Win64\Debug;"c:\program files (x86)\embarcadero\studio\20.0\lib\Win64\debug";
  "c:\program files (x86)\embarcadero\studio\20.0\lib\win64\release";"c:\program files (x86)\embarcadero\studio\20.0\lib\win64\release\psdk";
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64;C:\Users\Public\Documents\Embarcadero\Studio\20.0\DCP\Win64\Debug;
  C:\Users\Public\Documents\Embarcadero\Studio\20.0\Dcp\Win64 -l.\Win64\Debug -v -Gn -Tpe c0x64 .\Win64\Debug\File1.o , .\Win64\Debug\Project1.exe , 
  .\Win64\Debug\Project1.map , import64.a cw64mt.a , , Project1.res 
成功
経過時間: 00:00:02.8
```

コンパイルが通ってしまいましたね。

## 何故こういう事になるのか


### BCC32C / BCC32X

C++Builder 10.3 Rio では BCC32C 及び BCC32X が **C++17 対応**しています。なので、BCC32C ではコンパイルが通りません。先述の通りトライグラフは C++17 で廃止されています。

10.2 Tokyo 以前の BCC32C 及び BCC32X は C++11 対応です。[プロジェクト | オプション... ] で**従来の Borland コンパイラを使用**のチェックを外せば BCC32C が使われます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/c48ee435-05a9-dac7-ecae-5ec50bf06ce2.png)
なので、10.2 Tokyo だとコンパイルは通ります。

```
プロジェクトの依存関係を確認中...
Project1.cbproj をビルド中 (Debug, Win32)
bcc32c の "Project1PCH1.h" コマンド ライン
  c:\program files (x86)\embarcadero\studio\19.0\bin\bcc32c.exe -cc1 -D _DEBUG -n .\Win32\Debug -I C:\Users\OWNER\Documents\Embarcadero\Studio\Projects 
  -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\crtl\JA" -isystem "c:\program files 
  (x86)\embarcadero\studio\19.0\include\windows\rtl\JA" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include" -isystem "c:\program files 
  (x86)\embarcadero\studio\19.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\crtl" -isystem 
  "c:\program files (x86)\embarcadero\studio\19.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\rtl" 
  -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\vcl" -isystem C:\Users\Public\Documents\Embarcadero\Studio\19.0\hpp\Win32 
  -isystem "C:\Users\OWNER\Documents\tmssoftware\TMS Smooth Controls" -isystem "C:\Users\OWNER\Documents\tmssoftware\TMS Smooth 
  Controls\Delphi102Tokyo\Win32\Release" -isystem 
  C:\Users\OWNER\Documents\Embarcadero\Studio\19.0\CatalogRepository\SynEdit-1.3\Src\source\hpp\Win32\Debug -isystem 
  C:\Users\OWNER\Documents\Embarcadero\Studio\19.0\CatalogRepository\SynEdit-1.3\Src\source\hpp\Win32\Release -isystem 
  C:\Users\Public\Documents\Embarcadero\Studio\19.0\hpp\Win32 -g -fno-limit-debug-info -fborland-extensions -nobuiltininc -nostdsysteminc -triple 
  i686-pc-win32-omf -emit-pch -cxx-abi borland -masm-verbose -ffunction-sections -fexceptions -fcxx-exceptions -fseh -mdisable-fp-elim 
  -fno-spell-checking -fno-use-cxa-atexit -fno-threadsafe-statics -x c++ -std=c++11 -O0 -fmath-errno -tC -tM -o .\Win32\Debug\Project1PCH1.pch 
  -auto-dependency-output Project1PCH1.h 
bcc32c の "File1.cpp" コマンド ライン
  c:\program files (x86)\embarcadero\studio\19.0\bin\bcc32c.exe -cc1 -D _DEBUG -n .\Win32\Debug -I C:\Users\OWNER\Documents\Embarcadero\Studio\Projects 
  -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\crtl\JA" -isystem "c:\program files 
  (x86)\embarcadero\studio\19.0\include\windows\rtl\JA" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include" -isystem "c:\program files 
  (x86)\embarcadero\studio\19.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\crtl" -isystem 
  "c:\program files (x86)\embarcadero\studio\19.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\rtl" 
  -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\vcl" -isystem C:\Users\Public\Documents\Embarcadero\Studio\19.0\hpp\Win32 
  -isystem "C:\Users\OWNER\Documents\tmssoftware\TMS Smooth Controls" -isystem "C:\Users\OWNER\Documents\tmssoftware\TMS Smooth 
  Controls\Delphi102Tokyo\Win32\Release" -isystem 
  C:\Users\OWNER\Documents\Embarcadero\Studio\19.0\CatalogRepository\SynEdit-1.3\Src\source\hpp\Win32\Debug -isystem 
  C:\Users\OWNER\Documents\Embarcadero\Studio\19.0\CatalogRepository\SynEdit-1.3\Src\source\hpp\Win32\Release -isystem 
  C:\Users\Public\Documents\Embarcadero\Studio\19.0\hpp\Win32 -g -fno-limit-debug-info -fborland-extensions -nobuiltininc -nostdsysteminc -triple 
  i686-pc-win32-omf -emit-obj -cxx-abi borland -masm-verbose -ffunction-sections -fexceptions -fcxx-exceptions -fseh -mdisable-fp-elim 
  -fno-spell-checking -fno-use-cxa-atexit -fno-threadsafe-statics -main-file-name File1.cpp -x c++ -std=c++11 -O0 -fmath-errno -tC -tM -o 
  .\Win32\Debug\File1.obj -auto-dependency-output -MT .\Win32\Debug\File1.obj -include-pch .\Win32\Debug\Project1PCH1.pch File1.cpp 
[bcc32c 警告] File1.cpp(1): 3 文字表記が '#' 文字に変換されました
[bcc32c 警告] File1.cpp(2): 3 文字表記が '#' 文字に変換されました
[bcc32c 警告] File1.cpp(4): 3 文字表記が '#' 文字に変換されました
[bcc32c 警告] File1.cpp(5): 3 文字表記が '#' 文字に変換されました
[bcc32c 警告] File1.cpp(6): 3 文字表記が '#' 文字に変換されました
[bcc32c 警告] File1.cpp(11): 3 文字表記が '#' 文字に変換されました
[bcc32c 警告] File1.cpp(13): 3 文字表記が '[' 文字に変換されました
[bcc32c 警告] File1.cpp(13): 3 文字表記が ']' 文字に変換されました
[bcc32c 警告] File1.cpp(14): 3 文字表記が '{' 文字に変換されました
[bcc32c 警告] File1.cpp(17): 3 文字表記が '}' 文字に変換されました
brcc32 の "Project1.vrc" コマンド ライン
  c:\program files (x86)\embarcadero\studio\19.0\bin\cgrc.exe -c65001 Project1.vrc -foProject1.res 
ilink32 コマンド ライン
  c:\program files (x86)\embarcadero\studio\19.0\bin\ilink32.exe -G8 -L.\Win32\Debug;"c:\program files 
  (x86)\embarcadero\studio\19.0\lib\Win32\debug\JA";"c:\program files (x86)\embarcadero\studio\19.0\lib\Win32\release\JA";"c:\program files 
  (x86)\embarcadero\studio\19.0\lib\Win32\debug";"c:\program files (x86)\embarcadero\studio\19.0\lib\win32c\release";"c:\program files 
  (x86)\embarcadero\studio\19.0\lib\win32\release";"c:\program files (x86)\embarcadero\studio\19.0\lib\win32\release\psdk";
  "C:\Users\OWNER\Documents\tmssoftware\TMS Smooth Controls";"C:\Users\OWNER\Documents\tmssoftware\TMS Smooth Controls\Delphi102Tokyo\Win32\Release";
  C:\Users\Public\Documents\Embarcadero\Studio\19.0\DCP -j.\Win32\Debug;"c:\program files (x86)\embarcadero\studio\19.0\lib\Win32\debug\JA";"c:\program 
  files (x86)\embarcadero\studio\19.0\lib\Win32\release\JA";"c:\program files (x86)\embarcadero\studio\19.0\lib\Win32\debug";"c:\program files 
  (x86)\embarcadero\studio\19.0\lib\win32c\release";"c:\program files (x86)\embarcadero\studio\19.0\lib\win32\release";"c:\program files 
  (x86)\embarcadero\studio\19.0\lib\win32\release\psdk";"C:\Users\OWNER\Documents\tmssoftware\TMS Smooth Controls";
  "C:\Users\OWNER\Documents\tmssoftware\TMS Smooth Controls\Delphi102Tokyo\Win32\Release";C:\Users\Public\Documents\Embarcadero\Studio\19.0\DCP 
  -l.\Win32\Debug -v -Gn -Tpe  c0x32 .\Win32\Debug\File1.obj , .\Win32\Debug\Project1.exe , .\Win32\Debug\Project1.map , import32.lib cw32mt.lib , , 
  Project1.res 
成功
経過時間: 00:00:03.3
```

### BCC32
BCC32 は伝統的な Borland コンパイラの流れなので、トライグラフは TRIGRAPH.EXE を使って処理する前提です...なので当然の事ながらコンパイルは通りません。

### BCC64
10.3 Rio の BCC64 コンパイラは C++11 対応なのです。**まだ C++17 に対応していません。** 10.3 Rio において C++17 対応なのは BCC32C / BCC32X のみです。

C++Builder 10.3 Rio のコンパイラは以下のようになっています。

| コンパイラ | Clang ベース | 国際規格| 対応 OS|
|:---|:---:|:---:|:---|
|BCC32|<font color="Crimson">No</font>|| Windows 32bit|
|BCC32C [^3]|<font color="LimeGreen">Yes</font>|C++17| Windows 32bit|
|BCC32X [^3]|<font color="LimeGreen">Yes</font>|C++17| Windows 32bit|
|BCC64|<font color="LimeGreen">Yes</font>|C++11| Windows 64bit|
|BCCOSX|<font color="Crimson">No</font>|| macOS 32bit|
|BCCIOSARM|<font color="LimeGreen">Yes</font>|C++11| iOS 32bit|
|BCCIOSARM64|<font color="LimeGreen">Yes</font>|C++11| iOS 64bit|
|BCCAARM |<font color="LimeGreen">Yes</font>|C++11| Android 32bit|

C++11 に於いてはトライグラフはまだ有効でしたから BCC64 ではコンパイルが通ったのでした。

## TRIGRAPH.EXE

TRIGRAPH.EXE は **TurboC++ 1.0** にも含まれる事を確認しています。最初期の C++ から付属していたのですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/358e5340-2a0a-deee-b7d3-108936a17099.png)
そういえば TRIGRAPH.EXE ってどの段階で C++Builder に付属しなくなったのでしょう？C++Builder 2007 に付属してるのは確認しましたが...って、**この EXE 16bit アプリじゃないですか！** しかも 1992 年って **Windows 3.0 の頃のバイナリ！**

```
C:\Embarcadero\Studio\5.0\bin>TRIGRAPH
Trigraph  Version 1.0  Copyright (c) 1992 Borland International

Filter to remove or insert trigraphs in C source files,
and to handle backslash splicing outside of macros.

Works directly on source files, creating a backup file
with the extension .BAK, unless -n or -x switch is used.

USAGE: trigraph [options] <file spec> [<file spec> ...]

options:
        -nXXX   write output files to directory 'XXX'
        -u      UNDO    insert trigraphs
        -xXXX   create output files with extension 'XXX'
```
バイナリエディタで EXE を覗いてみると、コンパイラは Borland C++ 3.0 (1991 年) が使われてるようですね。[DOSBox](https://www.dosbox.com/) でも動作を確認しました。-u オプションでソースコードをトライグラフ化する事もできるのでしたね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/c9101e39-d9da-0534-3d05-59ddcf0807e8.png)
あー、64bit Windows では TRIGRAPH.EXE が動かないから添付しなくなったのかもしれませんね。しかもソースコードを (いないでしょうけど) UTF-16 (UCS-2) / UTF-32 (UCS-4) とかで保存したものは TRIGRAPH.EXE を通すと壊れるでしょうしね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/0f683c6e-b229-32b8-a6a7-d3fde6e50ad2.png)
ぶっちゃけトライグラフは使いませんので特に問題はないんですけどね (w

# おわりに

トライグラフの件をダシにしてしまいましたが、C++Builder 10.3 Rio ではデフォルトのコンパイラ (Win32) が変更になり、対応規格が他のクロスプラットフォーム用コンパイラと異なっているので注意が必要となっています。

例えばクロスプラットフォーム用に FireMonkey アプリケーションを作り、ライブラリのテストを Win32 でやるようにしていたけど、いざプラットフォームを切り替えたらコンパイルが通らない...なんて事があり得ます。

ちなみに BCC32 や BCCOSX は独自規格なのですが、C++0x を追いかけていた事もあり C++11 の一部機能が実装されています。詳しくは以下のリンク先を参照してみてください。

 - [Modern C++ 言語機能の準拠状況 (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/Modern_C%2B%2B_%E8%A8%80%E8%AA%9E%E6%A9%9F%E8%83%BD%E3%81%AE%E6%BA%96%E6%8B%A0%E7%8A%B6%E6%B3%81)

さて、(僕も含めて) **「せめて BCC64 を C++17 対応版にしてくれ！ (C++17 対応は Win32/Win64 同時にやれ)」** という声もあちこちで聞かれた C++Builder 10.3 Rio ですが、それはともかく C++17 に触れる事ができるというのはとてもいい事だと思います。

C++Builder 10.3 Rio には**無償版の Community Edition** もあります。Delphi と同時にインストールできないのが残念ですが、モバイル開発 (iOS / Android) もできますので C++ ができる方は (できない方も) ダウンロードしてみてはいかがでしょうか？
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/3b18f40e-9181-1b70-29ec-5252af66cd9a.png)](https://www.embarcadero.com/jp/products/cbuilder/starter)

- [C++Builder Community Edition (Embarcadero)](https://www.embarcadero.com/jp/products/cbuilder/starter)
- [Delphi / C++Builder Community Edition - Q&A (Embarcadero)](https://www.embarcadero.com/jp/products/delphi/starter/faq)
- [Delphi 10.3 Community Edition をインストール (Qiita: @CYonezawa)](https://qiita.com/CYonezawa/items/f0a14357b77c5ab19ca6) <- C++Builder で読み替えることができます
- [RAD Studio / Delphi / C++Builder 10.3 Rio スタートアップ FAQ (Qiita)](https://qiita.com/ht_deko/items/573f7c11c15c46f895c6)

**追記: 2019/07/19**
C++17 対応 Windows 64bit コンパイラ (BCC64) を含む **C++Builder 10.3.2 Rio** がリリースされました。

| コンパイラ | Clang ベース | 国際規格| 対応 OS|
|:---|:---:|:---:|:---|
|BCC32|<font color="Crimson">No</font>|| Windows 32bit|
|BCC32C [^3]|<font color="LimeGreen">Yes</font>|C++17| Windows 32bit|
|BCC32X [^3]|<font color="LimeGreen">Yes</font>|C++17| Windows 32bit|
|BCC64|<font color="LimeGreen">Yes</font>|C++17| Windows 64bit|
|BCCOSX|<font color="Crimson">No</font>|| macOS 32bit|
|BCCIOSARM|<font color="LimeGreen">Yes</font>|C++11| iOS 32bit|
|BCCIOSARM64|<font color="LimeGreen">Yes</font>|C++11| iOS 64bit|
|BCCAARM |<font color="LimeGreen">Yes</font>|C++11| Android 32bit|

これで Windows プラットフォームにおいては 32bit / 64bit 関係なく C++17 を使うことができるようになりました。

 - [Delphi / C++Builder / RAD Studio 10.3.2 リリースのお知らせ (Embarcadero Blog)](https://community.idera.com/developer-tools/b/blog/posts/announcing-the-release-of-delphi-c-builder-and-rad-studio-10-3-2-ja)

[^1]: \ (0x5C)。バックスラッシュ。日本だと円記号 (&yen;)。
[^2]: | (0x7C)。パイプ。何故か Qiita のマークダウンではテーブル内で ＼｜ とエスケープしても／になってしまう。
[^3]: 無償で公開されている [Free C++ Compiler](https://www.embarcadero.com/jp/free-tools/ccompiler) にもこのコンパイラが含まれている。