7

次のことを考慮してください。

#include <vector>
using namespace std;

struct Vec2
{
  float m_x;
  float m_y;
};

vector<Vec2> myArray;

int main()
{
  myArray.resize(100);

  for (int i = 0; i < 100; ++i)
  {
    myArray[i].m_x = (float)(i);
    myArray[i].m_y = (float)(i);
  }

  float* raw;
  raw = reinterpret_cast<float*>(&(myArray[0]));
}

正しいraw値で200個の連続したフロートがあることが保証されていますか?つまり、標準はこれを保証しますか?

編集:上記が保証されVec2ていて、いくつかの関数(非仮想)とコンストラクターがある場合、保証はまだありますか?

注:これは危険であることに気づきました。私の特定のケースでは、サードパーティのライブラリを使用しているため、選択の余地はありません。

4

3 に答える 3

5

これは危険だと思います。私の特定のケースでは、サードパーティのライブラリを使用しているため、選択の余地はありません。

構造体サイズのコンパイル時チェックを追加できます。

ライブデモ

struct Vec2
{
    float a;
    float b;
};

int main()
{
        int assert_s[ sizeof(Vec2) == 2*sizeof(float) ? 1 : -1 ];
}

それはあなたのアプローチの自信を高めるでしょう(前述のように、reinterpret_castのためにまだ安全ではありません)。


raw = reinterpret_cast(&(myArray [0]));

ISO C ++ 98 9.2 / 17:

reinterpret_castを使用して適切に変換されたPOD構造体オブジェクトへのポインターは、その初期メンバー(または、そのメンバーがビットフィールドの場合は、それが存在するユニット)を指し、その逆も同様です。[注:したがって、適切な配置を実現するために必要な場合、標準レイアウトの構造体オブジェクト内に名前のないパディングが存在する可能性がありますが、最初は存在しません。—エンドノート]


そして最後に、対応するアドレスの実行時チェックにより、そのようなソリューションはかなり安全になります。これは、単体テスト中、またはプログラムのすべての開始時(小さなテストアレイ上)で実行できます。

すべてを一緒に入れて:

ライブデモ

#include <vector>
#include <cassert>
using namespace std;
struct Vec2
{
    float a;
    float b;
};

int main()
{
    int assert_s[ sizeof(Vec2) == 2*sizeof(float) ? 1 : -1 ];
    typedef vector<Vec2> Vector;
    Vector v(32);
    float *first=static_cast<float*>(static_cast<void*>(&v[0]));
    for(Vector::size_type i,size=v.size();i!=size;++i)
    {
        assert((first+i*2) == (&(v[i].a)));
        assert((first+i*2+1) == (&(v[i].b)));
    }
    assert(false != false);
}
于 2012-11-04T22:20:17.387 に答える
3

いいえ、これは安全ではありません。コンパイラは構造内の2つの間または後にパディングを自由に挿入できるfloatため、構造のfloatsが連続していない可能性があるためです。

それでも試してみたい場合は、コンパイル時チェックを追加して、動作することをより確実にすることができます。

static_assert(sizeof(Vec2) == sizeof(float) * 2, "Vec2 struct is too big!");
static_assert(offsetof(Vec2, b) == sizeof(float), "Vec2::b at the wrong offset!");
于 2012-11-04T22:17:01.340 に答える
-1

与える唯一の保証は、キャストされたオブジェクトを元のデータ型に戻したreinterpret_castときに元のオブジェクトを取得することです。reinterpret_cast

特に、raw正しい値を持つ200個の連続したフロートがあることは保証されていません。

于 2012-11-04T22:15:52.437 に答える