2

引用を理解できません(具体的には、太字部分):

タイプ「cv1 void へのポインタ」の prvalue は、タイプ「cv2 T へのポインタ」の prvalue に変換できます。ここで、T はオブジェクト タイプであり、cv2 は cv1 と同じ cv-qualification またはそれより大きい cv-qualification です。元のポインタ値がメモリ内のバイトのアドレス A を表し、A が T のアラインメント要件を満たさない場合、結果のポインタ値は指定されません。

int i = 0;
void *vp = &i;
auto *res = static_cast<double*>(vp);

私の質問は次のとおりです。

  • res( のアドレス) が指すアドレスはint、 のアラインメント要件を満たしていますdoubleか?

  • 結果のポインタresには未指定の値がありますか?

  • そして、私がこのようなものを持っているとき:タイプはターゲットタイプより厳密ではありませんstatic_cast<double*>(static_cast<void *>(&i))
    か? この式の結果が不特定にならないようにidouble

4

1 に答える 1

2

res が指すアドレス (int のアドレス) は double のアラインメント要件を満たしていますか?

それは実装に依存します。ほとんどの場合、そうではありません。通常、 のアラインメント要件は のアラインメント要件intよりも小さくなりdoubleます。

たとえば、Linux などで使用される x86-64 System V ABI では、intアラインメント要件が4あり、.double8

たとえば、次のようにして、アライメント要件が満たされていることを確認できますstatic_assert

static_assert(alignof(int) >= alignof(double));

結果のポインター res は未指定の値を持っていますか?

アライメント要件が満たされていない場合 (つまり、static_assert失敗した場合)、はい。それ以外の場合は、オブジェクトを指しますi

そして、私がこのようなものを持っているとき: static_cast<double*>(static_cast<void *>(&i))

これは、スニペットに示されているものとまったく同じです。


アラインメント要件が満たされていても、resを使用して、それが指すオブジェクトの値にアクセスできないことに注意してください。これは、ポインターのエイリアシング規則に違反するためです。したがって、キャストの結果は何の役にも立たない可能性が非常に高くなります。

于 2022-02-26T16:38:20.667 に答える