文字コード変換プログラムのiconvでは、文字コード「UTF-8」において、入出力ともにBOMを用いません。
出力においてBOMを使わないということは、すぐに納得がいくことと思います。UTF-8として出力されるバイト列の先頭にBOMがつかないということです。
かたや、入力においてというのがどういうことかというと、BOMに相当するバイト列を
見ても、それをBOMとは認識しないということです。
つまり、データ先頭にEF BB BFという3バイトがあったら、それをBOMとして消費するのでなく、単なる普通の1文字のように扱うのです。
ちょっと実験してみましょう。
UTF-8にBOMを付けて出力するプログラムとしてポピュラーなのはWindowsのメモ帳です(XPで確認)。メモ帳でUTF-8としてテキストを保存するともれなくBOMがついてきます。
例えば、メモ帳で「あ」とだけ書いて改行し、UTF-8で保存する。すると、EF BB BF E3 81 82 0D 0A というバイト列になる。
これをiconvでShift_JISに変換しようとする。「あ」と書いてあるだけなのだから問題ない筈と思いきや、これがうまくいかない。
$ iconv -f UTF-8 -t SHIFT_JIS a.txt > a-s.txt
iconv: illegal input sequence at position 0
なんと、エラーでとまってしまいます。
なぜかというと、先頭のEF BB BFをBOMとみなすのでなくテキストの一部と解釈し、U+FEFFの文字をShift_JISに変換しようとして、Shift_JISには該当する文字がないので、当然のごとく失敗しているわけです。
この場合、iconvにオプション -c を付けて、変換できない文字を無視するようにすればエラーなく通ります。
また、上のUTF-8テキストをUTF-16に変換しようとするとこうなります。ここではUTF-16BEやUTF-16LEでなく、UTF-16を指定します。つまり、BOMを用います。
$ iconv -f UTF-8 -t UTF-16 a.txt | hd
00000000 ff fe ff fe 42 30 0d 00 0a 00 |....B0....|
なんと、BOMが2つ並ぶという残念な結果になってしまいます(先頭のff feがBOM)。もう説明の必要はないと思いますが、UTF-8テキストの先頭の3バイトがBOMとして解釈されず、UTF-16を出力するときに改めてBOMを付けようとするので、こういう結果になっています。
上で使った出力のUTF-16はBOMを用いますが、ではBOMを付けないつもりでUTF-16BE を指定するとどうなるか。大体想像がつくと思いますが、こうなります。
$ iconv -f UTF-8 -t UTF-16BE a.txt | hd
00000000 fe ff 30 42 00 0d 00 0a |..0B....|
iconvの入力にUTF-8を指定するときは、入力データにBOMがついていないことを確認しておくのが良さそうです。