2017-04-05 5 views
2

私は構造体mainsetへのポインタを取り、へのポインタにこれを回す必要がトリッキーな状況にいるよ基本的な問題フィールド

数の少ない他のstruct型に構造体へのポインタをキャスト構造体subsetで、そのフィールドはフィールドの連続したサブセットであるmainsetで、最初から始まります。そのようなことは、明確な行動をとって可能ですか?これはかなり恐ろしいことだとわかっていますが、私はそれを行うための良い、不満足な理由があります[患者の読者のために底に説明]。実装が打ち鳴らすコンパイラとOS X上で、動作するようにを思わ

私の試みは:私は期待どおり

#include <iostream> 

struct mainset { 
    size_t size; 
    uint32_t reflex_size; 
}; 

struct subset { 
    size_t size; 
}; 

using namespace std; 
int main(int argc, char *argv[]) { 
    mainset test = {1, 1}; 
    subset* stest = reinterpret_cast<subset*>(&test); 
    std::cout << stest->size << std::endl; 
} 

出力は、実際に1です。しかし、私は思う:私はちょうど特定のコンパイラと単純なケース(実際には私の構造体はより複雑です)で幸運を得ている、またはこれは一般的に動作しますか?

また

、フォローアップの質問:他の迷惑な理由のために、私は余分なフィールドが前面に来て、代わりに私の大きな構造体

struct mainset { 
    uint32_t reflex_size; 
    size_t size; 
}; 

を行う必要があるかもしれないと心配しています。この場合、私の実装を拡張することができますか? &test&test+sizeof(test.reflex_size)に置き換えようとしましたが、これはうまくいかなかった。 cout文の出力は、私がこの

私のプロジェクトは、線形代数のためのGSLライブラリを使用しなければならない理由の0

説明しました。このライブラリは、フォーム

struct gsl_block { 
    size_t size; 
    double* data; 
} 

gsl_vectorgsl_matrixのような類似した構造体の構造体を利用します。だから、私はこれらの構造体を私のC++クラスのメンバーとして使用しました。問題ない。しかし、私のプロジェクトで最近要求される機能は、ROOTエコシステムの一部であるReflexツールを使用して自分のクラスに反映させることです。リフレックスで、このような構造体の反射を可能にするために、私は

struct gsl_block { 
    size_t size; 
    double* data; //[size] 
} 

このアノテーションは、配列の長さは同じ構造体のフィールドsizeによって提供されていることをことを反射を伝えるようにアノテーションを追加する必要があります。通常はそれはだが ReflexとROOTは非常に不幸な制限がある。長さフィールドは32ビットでなければならない。この制限はすぐには解決されず、自分自身で解決する時間やリソースがないという通知を受けて、私は回避策を探しています。私の考えは、何らかの形でより大きな構造体の中gsl_blockを持つ構造体のビット互換埋め込むことです:

struct extended_gsl_block { 
    size_t size; 
    double* data; //[reflex_size] 
    uint32_t reflex_size; 
} 

gsl_vectorgsl_matrixについても同様の事。私はreflex_sizesizeが常に等しいことを保証することができます(どちらも〜50より大きくはない)。そして、Reflexはこのヘッダを正しく解析することができます(reflex_sizeがフィールドの前に必要な場合、 。GSLルーチンはこれらの構造体へのポインタで動作するので、私の考えは次のとおりです。ポインタextended_gsl_block*を与えられたら、ちょうどフィールドsizedatareinterpret_castのポインタをgsl_block*に入力します。

答えて

2

あなたは幸運です。

例として示すクラスは、の標準レイアウトタイプの要件に準拠しています。

あなたはここで多くを読むことができます:

http://en.cppreference.com/w/cpp/language/data_members#Standard_layout

をあなたがして、コンパイラにこの前提をテストすることができます。

static_assert(std::is_standard_layout<gsl_block>::value, "not a standard layout"); 
+0

ありがとう!コンサルティングは、すべてのデータ型が非静的で非参照型なので(構造体はすべてC構造体なので)、私が作業しているすべての型を伝えることができます。だから、うまくいけば私の運が続く。道路の下に細かい細部があるかもしれません。特に、これらの構造体にどのようにメモリが割り当てられているかについて... – jwimberley

関連する問題