312
166

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C++Advent Calendar 2023

Day 4

「//このコメントを消したら動かない」は大体Shift_JISの2バイト目が原因で発生する

Last updated at Posted at 2023-12-04

TL;DR

Shift_JISにしただけでコンパイラが通らなくなる恐ろしい事件とその回避法について。

  • \ (¥)のASCIIコードは0x5c
  • 表、能は良くない
  • UTF-8は神

2023/12/06追記

誤りがあったので訂正します。こんな読まれると思ってなかったので正直ちょっとびっくりしていますが、いろいろコメントありがとうございました。(ツイート等全て拝見しました。)

  • Shift_JISが悪いわけではない(デフォルトのエンコーディング設定の問題)→追記しました
  • UTF-8にはUTF-FSSという仕様でこの問題が回避されている→マジでタメになる知識ありがとうございます
  • OSによってデフォルトのエンコーディング設定が異なるせいで、デフォルト環境での動作がOSにより異なる→なるほど?(調査中)
  • CRLFとLF問題では→なるほど?(調査中)
  • そんな問題何を今更→UTF-8が出てから生まれたからです。

\を改行とみなすかどうか

C言語のコンパイラは\が行末に来ると改行を無視します。

int main(void) {
    //この行はコメントだよー \
    この行もコメント
    この行はコメントではない
    return 0;
}

例えば、このプログラムはエラーになるのでダメです。

int main(void) {
    //うわー \
    if (1) {
    }
    return 0;
}

これはif(1) {がコメントと解釈されると、それに対応する中括弧が対応しなくなるためです。

本題 Shift_JISのトラップ

ここからが本題です。

int main(void) {
    //あいうえお
    if (1) {
    }
    return 0;
}

このプログラムは問題なくコンパイルできます。(そりゃぁそう)

int main(void) {
    //プログラムの才能
    if (1) {
    }
    return 0;
}

しかしこちら、Shift_JISで保存してコンパイルすると、エラーが起こることがあります。は?

アートボード 1.png

\ (¥)のASCIIコードは0x5cなので、エンコーディングの設定が間違っているとコンパイラが能の2バイト目を\と解釈してしまいます。そうするとif(1) {が無視されてエラーとなります。

他にもこのような文字は存在していて、全部書くと書ききれないのですがよく使いそうなものだと

です。表・能・欺とかは割と文末に来ることが多いので注意です。

これらは下位バイトが5cなのでShift_JISでプログラミングするときに行末にあってはいけません。ダメ文字1と一部界隈はよばれているそうです。

結局あのコメントはなんだったのか

int main(void) {
    //プログラムの才能
    //このコメントを消したらなぜか動かない
    if (1) {
    }
    return 0;
}

先ほどの説明を踏まえるとこのコメントを説明できます。能の次の行がコメント(又は空白行)だと\と解釈されても次の行がプログラム的に意味を持たないため問題なくコンパイルできます。

対策

  • ダメ文字を使わない
  • Shift_JISを使わない
  • 正しくエンコーディング設定をする

ちなみに先ほどの能が文末にくるプログラムは、UTF-8ではUTF-FSSにより下位バイトが5cになることはない2ので(流石!!)問題なくコンパイルできます。

コンパイル時にエンコーディングを正しく設定するとこの問題は発生しませんが、特別な理由でもない限りUTF-8で保存するのが無難だと思います。

Shift_JISの名誉のために

Shift_JISさん悪く言ってごめんなさい。確かにバイト数が少なく済むのはいいと思うのでがんばってね。俺は使わないけど。

まとめ

Shift_JISやめましょう

参考文献

  1. 文字コード表 シフトJIS(Shift_JIS) http://charset.7jp.net/sjis.html
  1. https://ja.wikipedia.org/wiki/Shift_JIS#2バイト目が5C等になりうることによる問題

  2. https://ja.wikipedia.org/wiki/UTF-8

312
166
11

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
312
166

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?