// No effective type yet because there has been no write to the memory.
Foo *f = malloc(sizeof(Foo));
ここにはアクセスがなく、オブジェクトもありません。有効なタイプは関係ありません。最初のsizeof(フー)で
// Effective type of `f` is now `Foo *`, except I'm writing to
// `f->n`, so shouldn't it be `int *`? Not sure what's going on here.
f->n = 1;
オブジェクトは、アドレスFでバイト有効なタイプはFooを有し、第1のsizeof(INT)でオブジェクトがアドレスFでバイト有効なint型を有しています。
// No effective type yet because there has been no write to the memory.
char *buf = malloc(sizeof(Foo));
ここにはオブジェクトはありません。有効なタイプは関係ありません。最初のsizeof(フー)で
// Effective type of `buf` is `Foo *`, despite it being declared as
// `char *`.
// It's not safe to modify `buf` as a `char` array since the effective type
// is not `char`, or am I missing something?
memcpy(buf, f, sizeof(Foo));
オブジェクトアドレスにバイトしかし、効果的なタイプのFooを有し、第1のsizeof(INT)でオブジェクトがアドレスにバイトが、有効なint型を有しています。
有効なタイプに関係なく、任意のオブジェクトに文字タイプでアクセスできます。 bufのバイトにcharでアクセスできます。
// The cast here is well defined because effective type of `buf` is
// `Foo *` anyway, right?
((Foo *)buf)->n++;
はい。式全体が有効です。
// I'm not even sure this is OK. The effective type of `buf` is `Foo *`,
// right? Why wouldn't it be OK then?
memcpy(f, buf, sizeof(Foo));
これは問題ありません。 memcpyは、アドレスfのオブジェクトの型を型Fooに変更します。 fが前にFoo型を持っていなかったとしても、それは今です。
// Safe if the last `memcpy` was safe.
f->n++;
はい。
// buf now points to invalid memory.
free(buf);
はい。
// Pointers with different declared types point to the same object,
// but they have the same effective type that is not qualified by
// `restrict`, so this doesn't violate strict aliasing, right?
// This is allowed because `f` was allocated via `malloc`,
// meaning it is suitably aligned for any data type, so
// the effective type rules aren't violated either.
buf = (void *)f;
あなたはコンセプトをミックスしています。個々のポインタの制限と値はエイリアシングには関係ありません。アクセスはです。ポインタbufは単にアドレスfを指します。
// `f`, and consequently `buf` since it points to the same object as `f`,
// now point to invalid memory.
free(f);
はい。
'buf =(void *)f'は常に' 'f''の型にかかわらず有効です。厳密なエイリアシング規則には' 'char * ''が他の型のエイリアスを許す例外があるからです。 – user3386109