まず、明確にするために、無効なポインターの逆参照について話しているのではありません。
次の 2 つの例を考えてみましょう。
例 1
typedef struct { int *p; } T;
T a = { malloc(sizeof(int) };
free(a.p); // a.p is now indeterminate?
T b = a; // Access through a non-character type?
例 2
void foo(int *p) {}
int *p = malloc(sizeof(int));
free(p); // p is now indeterminate?
foo(p); // Access through a non-character type?
質問
上記の例のいずれかが未定義の動作を呼び出しますか?
環境
この質問は、この議論に応えて提起されます。たとえば、ポインタ引数が x86 セグメント レジスタを介して関数に渡され、ハードウェア例外が発生する可能性があるという提案がありました。
C99 標準から、次のことを学びます (強調は私のものです)。
[3.17] 不定値- 未指定の値またはトラップ表現のいずれか
その後:
[6.2.4 p2]ポインタが指すオブジェクトがその存続期間の終わりに達すると、ポインタの値は不確定になります。
その後:
[6.2.6.1 p5]特定のオブジェクト表現は、オブジェクト タイプの値を表す必要はありません。オブジェクトの格納された値がそのような表現を持ち、文字型を持たない左辺値式によって読み取られる場合、動作は undefinedです。そのような表現が、文字型を持たない左辺値式によってオブジェクトのすべてまたは一部を変更する副作用によって生成される場合、動作は未定義です。このような表現はトラップ表現と呼ばれます。
これらすべてをまとめると、「死んだ」オブジェクトへのポインタへのアクセスにはどのような制限があるのでしょうか?
補遺
上記で C99 標準を引用しましたが、C++ 標準のいずれかで動作が異なるかどうかを知りたいです。