2017-11-09 15 views
-1

既にこのトピック(特にHow to get address of some struct member in array of structures)について質問があります。マップファイル内のメンバー構造のアドレス?

私たちがstructを使用してハードウェアデバイスを記述すると、各構造メンバーはハードウェアデバイスのいくつかのレジスタに対応するでしょう - 構造の各メンバーが正しくマップされているかどうかハードウェアの各レジスタ?

コンパイラのABIはメンバーの配置を指示しますが、ユーザーは間違いを犯す可能性もあります。マッピングが正しく行われたかどうかを確認する唯一の方法は、実行時に確認することです。 マップファイル(少なくともGNU ld用)は、構造体メンバの配置に関するヒントを提供しません。

コンパイラーやリンク時に各構造メンバーがどこにあるのか知る方法はありますか?

+1

あなたは正しいですが、これは移植可能な方法では不可能です。あなたは特定のコンパイラの拡張機能や動作に頼らなければなりません – Ctx

+0

これはとにかくシステム固有のものです。コードをまったく異なる種類のコンピュータに移動すると、ハードウェアデバイスはそこには存在しません。 –

+0

は絶対合意し、(CPU、コンパイラ)に依存します。しかし、同じCPUと同じコンパイラでも、マッピングに間違いがないことを確認したいと思います。マップファイルを使用して構造メンバーのマップを表示する方法を探しています。しかし、唯一の方法は、実行時にそれらのアドレスを表示するコードを持つことです。 –

答えて

2

offsetofは、C++ではstatic_assertと一緒に使用できます。例えば

、完全に任意

#include <cstddef> 
struct iom {  // off,len 
    uint32_t rx; // +0,4 
    uint32_t tx; // +4,4 
    uint64_t clk; // +8,8 
    uint16_t irq; // +16,2 
}; 
static_assert(offsetof(iom,rx)==0); 
static_assert(offsetof(iom,tx)==4); 
static_assert(offsetof(iom,clk)==8); 
static_assert(offsetof(iom,irq)==16); 

あなたのコンパイラが64ビット境界にメンバーを揃えているためstatic_assertは、例えば、失敗した場合は、アライメントとパディングを変更するコンパイラ固有の方法が必要です。たとえば、gccで、

} __attribute__((packed)); 

が構造体定義の最後にあります。


NB。私はC++に答えました17。

static_assertの2番目の引数として、C++ 11または14、またはC11にエラーメッセージが必要ですが、マクロ全体をラップして素敵な文字列を作成できます。

offsetofマクロもC言語で動作します。

+0

私はそれを確認するように促してくれてありがとう、私は知らなかった。 – Useless

+0

は私のコンパイラ(C11)でうまくいきます - Thx !! –

関連する問題