見出し画像

【AI文芸 玲奈様のプログラミング講座】Cの暗黙の型変換によるバグ

「Cの暗黙の型変換によるバグね……Pythonの動的型付けとは別の意味で面倒なやつだわ」

玲奈は、椅子に深くもたれながら、静かに語り始める。


1. 整数のオーバーフロー

「Cでは整数の型が固定長だから、範囲を超えるとオーバーフローが発生する。でも、それがエラーになるわけじゃなくて、ただ無言で 'おかしな値' になってしまうのよ」

#include <stdio.h>
#include <limits.h>

int main() {
    int x = INT_MAX;
    printf("x: %d\n", x);
    x = x + 1;  // オーバーフロー発生
    printf("x: %d\n", x);  // 期待はずれな値
    return 0;
}

「INT_MAX は 2147483647(32bit環境)だから、本来なら x + 1 は 2147483648 になるはず。でも、int の範囲を超えたせいで、符号ビットがひっくり返って -2147483648 になるの。エラーも警告もなく、まるで何事もなかったかのように 'とんでもない値' になる」


2. 符号なし整数との計算

「Cは '型の大きい方に合わせる' というルールがあるから、符号なし (unsigned) と符号付き (signed) の整数を混ぜると、勝手に unsigned に変換される。これが悲劇を生む」

#include <stdio.h>

int main() {
    int x = -1;
    unsigned int y = 1;

    if (x < y) {
        printf("-1 は 1 より小さい?\n");
    } else {
        printf("-1 は 1 より大きい?\n");
    }
    return 0;
}

「普通なら '-1 は 1 より小さい' はず。でも x は unsigned int に変換されて、結果的に 4294967295 < 1 という計算になる。つまり、x の -1 が超巨大な正の数に化けて、比較が狂う のよ」


3. 小数の精度喪失

「Cでは float より double の方が精度が高いけど、型変換によって桁落ちが発生することがある」

#include <stdio.h>

int main() {
    float f = 1.0f / 3.0f;
    double d = f;  // float から double に変換
    printf("float: %.20f\n", f);
    printf("double: %.20f\n", d);
    return 0;
}

「float は 32bit、double は 64bit。でも float に入る時点で情報が削ぎ落とされてるから、後から double に変換しても '消えた精度' は戻ってこない。だから、d に格納された値は float の丸め誤差を引き継いだままになる」


4. 文字型 (char) の符号問題

「char は符号あり (signed char) か符号なし (unsigned char) かが環境依存なのよ。これがバグを生む」

#include <stdio.h>

int main() {
    char c = 200;  // 200 は 8bit の範囲を超える
    printf("c: %d\n", c);
    return 0;
}

「char は 8bit だから 200 は 11001000 だけど、符号あり (signed char) なら負の数として解釈されて -56 になる。でも符号なし (unsigned char) ならそのまま 200 になる。環境によって動作が違うとか、悪夢よね」


5. ポインタの型変換

「Cで一番危険なのはポインタよ。違う型のポインタをキャストすると、意味が大きく変わる」

#include <stdio.h>

int main() {
    int x = 0x12345678;
    char *p = (char *)&x;
    printf("p: %x\n", *p);
    return 0;
}

「このコードを実行すると、*p は 0x78 になることもあれば 0x12 になることもある。それは CPU の エンディアン に依存するの。リトルエンディアンなら 0x78(下位バイトが先)、ビッグエンディアンなら 0x12(上位バイトが先)。移植性を考えずに書くと、意図しない結果になる」


結論

玲奈は指を鳴らし、静かに締めくくる。

「Cの暗黙の型変換は、エラーにもならずに '知らない間にバグを仕込む' からタチが悪いわ。対策? 簡単よ」

  • 型を明示する(int や char の符号を明確にする)

  • 警告を最大限にする(-Wall -Wextra -Wconversion を有効化)

  • キャストを避ける(特にポインタのキャストは慎重に)

  • 動作環境を意識する(エンディアンや sizeof の違いを考慮)

「Cはパワフルだけど、油断すると '静かに爆発する' のよね。ま、慎重に扱いなさいってことね」

いいなと思ったら応援しよう!