4
このコードを検討してください。パディングの存在が保証されています。これらstatic_assert
sの構造体または共用体のパディングにアクセスすることは安全ですか?
static_assert(_Alignof(char) < _Alignof(double), "Flip!");
static_assert(sizeof(char) < sizeof(double), "Flop!");
struct S {
char c[1];
double d;
};
union U {
char c[1];
double d;
};
static_assert(sizeof(struct S) == _Alignof(double) * sizeof(double), "Fudge!");
static_assert(sizeof(union U) == sizeof(double), "Futz!");
S s; U u;
s.c[1] = 0; // What?
u.c[1] = 0; // What?
、それはパディングが途中または末尾にありますのは間違いないだろう。それらにアクセスすることは安全ですか?
これはUBです。可能であれば、コンパイラはデバッグビルドの配列のバインドチェックを行うことができるため、UBです。 punnig型に関しては、次のような疑問があります。[C99で型宣言されていないユニオンを使って、C11で指定されていますか? 質問](https://stackoverflow.com/questions/11639947/is-type-punning-through-a-union-unspecified-in-c99-and-has-it-become-specified) – Ivan
alligbnmentはあまりない隣接フィールドのために通常は検出されない配列をオーバーロードすることになりますが、 'c [1]'はエラーです –
パディングに確実にアクセスすることはできません。構造体(共用体)割り当ての下でコピーされるパディングに頼ることはできません。そこにはバイトがあるという意味でそれらにアクセスすることは "安全"です。彼らと一緒にできることは何も意味がなく信頼できるものではありません。このようなバイトを使用する場合は、明示的に 'struct S2 {char c [1];ショートs; int i;ダブルd; } '(32ビットIntel x86を除くほとんどのシステムでは、' struct S'と同じサイズになります)。私はあなたの最初の静的なアサーションは32ビットx86で発生すると信じています。 –