[C言語] Cプログラミングの落とし穴 4.5 外部の型のチェックP68 境界値分析

『Cプログラミングの落とし穴』(A.コーニグ, 1990)
[M1 Mac, Big Sur 11.7.2, clang 13.0.0, NO IDE]

intの最大値付近が16進数ではどうなっているのか調べました。

intの最大値2147483647の16進数での次の値は10進数では-2147483648となっていて1ずつ増えていき最後に-1になります。この値の次がintの範囲を超えた数値になります。

4バイトをあてがったintの最大値は(2^8)^4/2 -1=2147483647のように算出できます。

int int_max_m1, int_max, int_max_p1, int_m1, int_m1_p1;
long long_m1_p1, long_A;

int main() {
    int_max_m1= 2147483646; // intの最大値 -1
    int_max = 2147483647; // intの最大値
    int_max_p1 = 2147483648; // intの最大値 +1
    int_m1 = -1;
    int_m1_p1 = 0x100000000; // int最大値の次の値 int
    long_m1_p1 = 0x100000000; // int最大値の次の値 long
    long_A = 4294967295; // int:-1


    printf("10進数\n");
    printf("int_max_m1 : %d\n", int_max_m1);
    printf("int_max : %d\n", int_max);
    printf("int_max_p1 : %d\n", int_max_p1);
    printf("int_m1 : %d\n", int_m1);
    printf("int_m1_p1 : %d\n", int_m1_p1);
    printf("long_m1_p1 : %ld\n", long_m1_p1);
    printf("long_A : %ld\n", long_A);

    printf("16進数\n");
    printf("int_max_m1 : %x\n", int_max_m1);
    printf("int_max : %x\n", int_max);
    printf("int_max_p1 : %x\n", int_max_p1);
    printf("int_m1 : %x\n", int_m1);
    printf("int_m1_p1 : %x\n", int_m1_p1);
    printf("long_m1_p1 : %lx\n", long_m1_p1);
    printf("long_A : %lx\n", long_A);

    return 0;
}
10進数
int_max_m1 : 2147483646
int_max : 2147483647
int_max_p1 : -2147483648
int_m1 : -1
int_m1_p1 : 0
long_m1_p1 : 4294967296
long_A : 4294967295
16進数
int_max_m1 : 7ffffffe
int_max : 7fffffff
int_max_p1 : 80000000
int_m1 : ffffffff
int_m1_p1 : 0
long_m1_p1 : 100000000
long_A : ffffffff

[C言語] Cプログラミングの落とし穴 4.5 外部の型のチェックP68

『Cプログラミングの落とし穴』(A.コーニグ, 1990)
[M1 Mac, Big Sur 11.7.2, clang 13.0.0, NO IDE]

2ヶ月と2週間ぶりに戻ってきました。

別ファイルの型宣言が間違っている場合の検証です。

gccでは警告が出て、clangはスルー、いずれもビルドが通りました。相変わらずclangはゆるいです。

# include "test2.h"

int n;

int main() {
    n = 2147483648; // intの最大値 2147483647の次は-2147483648になる(2の補数形式)
    // n = 9223372036854775807; // longの最大値ではエラーになる
    func(n);

    return 0;
}
#include <stdio.h>

extern long n;

void func(long n) {

    printf("n : %ld\n", n);

    return;
}
n : -2147483648
// clangは警告なし

// gccは警告あり
src/test.c:7:9: warning: implicit conversion from 'long' to 'int' changes value from 2147483648 to -2147483648 [-Wconstant-conversion]
    n = 2147483648;
      ~ ^~~~~~~~~~
1 warning generated.
(lldb) memory read -c32 0x0000000100008010
0x100008010: ff ff ff ff ff ff ff 7f 00 00 00 00 00 00 00 00  ................
0x100008020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................