インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

コンパイラーがポインターの範囲情報を定義する方法

ポインターチェッカーは、macOS* システムではサポートされていません。

コンパイラーがポインターの範囲情報を定義する方法について次に説明します。

各セクションで、lower_bound(p)p に関連付けられている下限を指し、upper_bound(p)p に関連付けられている上限を指します。

alloca() 関数で作成されたポインター

p = alloca(size);
    // lower_bound (p) は (char *)p
    // upper_bound (p) は lower_bound(p) + size - 1

calloc() 関数で作成されたポインター

p = calloc(num, size);
    // lower_bound(p) は (char *)p
    // upper_bound(p) は lower_bound(p) + size * num - 1

malloc() 関数で作成されたポインター

p = malloc(size);
    // lower_bound(p) は (char *)p
    // upper_bound(p) は lower_bound(p) + size - 1

キャストで作成されたポインター

p = (T *)q;
    // lower_bound(p) は lower_bound(q)
    // upper_bound(p) は upper_bound(q)

ポインターのキャストはポインターの範囲に影響しません。元のポインターに関連付けられている範囲よりも大きな新しい型にポインターをキャストした場合、元の範囲外のメンバーや要素にアクセスすると範囲外エラーが発生します。元のポインターよりも小さな型にポインターをキャストした場合、今までどおり元のデータにアクセスできます。

構造体の可変長配列用に作成されたポインター

typedef struct {
	int num;
	int a[];
} T;

q = malloc(sizeof(T) + sizeof(int) * num);
p = &q->a;
    // lower_bound(p) は (char *)&q->a
    // upper_bound(p) は upper_bound(q)

配列を構造体の最後のメンバーとして定義する場合、上限は変更されず、malloc() 関数で割り当てられたすべての配列要素にアクセスできます。

アドレス (&) 演算子で定義されたポインター

p = &v;
    // lower_bound(p) は (char *)&v
    // upper_bound(p) は (char *)&v + sizeof(v) - 1

p = &v.m;
    // lower_bound(p) は (char *)&v + offsetof(typeof(v),  m)
    // upper_bound(p) は lower_bound(p) + sizeof(v.m) - 1

p = &q->m;
    // lower_bound(p) は (char *)q + offsetof(typeof(*q),  m)
    // upper_bound(p) は lower_bound(p) + sizeof(q->m) - 1

構造体、共用体、クラスのメンバーを指す場合、範囲情報はメンバーのサイズに変更されます。

new 演算子で定義されたポインター

p = new T;
    // lower_bound(p) は (char *)p
    // upper_bound(p) は lower_bound(p) + sizeof(T) - 1

配列のアドレスで定義されたポインター

T a[X][Y];

p = a;
p = &a[x];
p = &a[x][y];
    // lower_bound(p) は (char *)a
    // upper_bound(p) は lower_bound(p) + sizeof(a) - 1

配列の要素のアドレスまたは多次元配列の単一行のアドレスを使用する場合、範囲は要素のサイズに変更されません。配列全体のポインターをインクリメントまたはデクリメントすることができます。

ポインターのインクリメントまたはデクリメント

p = &a[x][y].m;
    // lower_bound(p) は (char *)&a[n][m] + offsetof(T, m)
    // upper_bound(p) は lower_bound(p) + sizeof(T.m) - 1

要素のメンバーのアドレスを使用する場合、範囲はメンバーのサイズに変更されます。

ポインターのコピーで定義されたポインター

p = q;
p = q + expr;
p = q - expr;
    // lower_bound(p) は lower_bound(q)
    // upper_bound(p) は upper_bound(q)

範囲は q からコピーされます。右辺のポインターのオフセットは範囲に影響しません。

ポインターをインクリメントまたはデクリメントして定義されたポインター

p++;
p--;
++p;
--p;
p += expr;
p -= expr;

範囲はポインターをインクリメントまたはデクリメントしたときに変更されません。