SJISでコーディングしてはいけない、たった一つの理由


ダメ文字を意識しながらコーディングしなければならないからです。

ダメ文字とは?

Shift_JISのダメ文字
ダメ文字一覧表

a.c
#include <stdio.h>

void func(int x){
    // 与えられた変数を表示するだけの機能
    printf("%d\n", x);
    return;
}

int main(void){
    // ビット表
    int bitmap[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

    func(bitmap[0]);
}

このプログラムをSJIS(Shift-JIS)で保存しコンパイルすると、エラーが発生します(UTF-8で保存してコンパイルすると、エラーは発生しません)。

$ gcc a.c
a.c: 関数 ‘main’ 内:
a.c:13:10: エラー: ‘bitmap’ が宣言されていません (この関数内での最初の使用)
     func(bitmap[0]);
          ^
a.c:13:10: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます

変数bitmapは宣言されているにも関わらず、「‘bitmap’ が宣言されていません」というエラーが発生します。

原因は「表」

「// ビット表」というコメントがありますが、「表」はダメ文字です。この「表」という文字の2byte目は「\」です。つまり行の終わりに「\」と書かれていることと同じになります。これはC言語においては次の行までコメントアウトされてしまいます。

しょうがないので修正してなんとかしましょう。

a.c
#include <stdio.h>

void func(int x){
    // 与えられた変数を表示するだけの機能
    printf("%d\n", x);
    return;
}

int main(void){
    // ビット表
    // 「このコメントを削除するとなぜかコンパイルエラーが起きる」という現象が起きる
    int bitmap[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

    func(bitmap[0]);
}

さて、上記のように修正したプログラムを再度コンパイルします。今度はコンパイルエラーは発生しません。コンパイル成功です!プログラムを実行してみましょう。

$ gcc a.c
$ ./a.exe
(何も表示されない)

本来なら「1」を出力するはずですが、何も表示されませんでした。

原因は「能」

「// 与えられた変数を表示するだけの機能」というコメントがありますが、「能」もダメ文字です。この「能」という文字の2byte目は「\」です。つまりさっきと同じ現象で、次の行までコメントアウトされてしまっている(printf文がコメントアウトされてしまっている)ので、何も表示されなかったわけです。

しょうがないのでプログラムを修正しましょう。

a.c
#include <stdio.h>

void func(int x){
    // 与えられた変数を表示するだけの機能.
    printf("%d\n", x);
    return;
}

int main(void){
    // ビット表
    // 「このコメントを削除するとなぜかコンパイルエラーが起きる」という現象が起きる
    int bitmap[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

    func(bitmap[0]);
}

「能」の後ろに適当に「.」を付けました。これで次の行までコメントアウトされることはなくなります。再度コンパイルして実行してみましょう。

$ gcc a.c
$ ./a.exe
1

これでOKです!

「これでOKです!」じゃない

このままだとダメ文字を意識しながらコーディングをし続けないといけません。
そもそもSJISでコーディングせず、UTF-8でコーディングするようにしましょう。