[解決済み] C++のクラスメモリ構造で「スペーサー」を作成するにはどうしたらいいですか?
質問
問題
で 低レベルのベアメタル組み込み コンテキストで、私は、C++ 構造内に、名前のない空白のスペースをメモリ内に作成し、ユーザーがそのメモリ位置にアクセスするのを禁止したいと思います。
今現在、私は醜い
uint32_t :96;
というビットフィールドを置くことで実現しました。これは都合よく3つの単語の代わりになりますが、GCCから警告(Bitfield too large to fit in uint32_t)を出します。
問題なく動作しますが、数百ものこれらの警告があるライブラリを配布したい場合、あまりきれいではありません...。
どうすれば適切にできるのでしょうか?
そもそも、なぜ問題が発生するのでしょうか?
私が取り組んでいるプロジェクトは、マイクロコントローラ (STMicroelectronics STM32) 全体のさまざまな周辺機器のメモリ構造を定義することで構成されています。これを行うには、ターゲットとなるマイクロコントローラーに応じて、すべてのレジスタを定義する複数の構造体のユニオンを含むクラスが必要となります。
かなり単純なペリフェラルの例として、汎用入出力(GPIO)があります。
union
{
struct
{
GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
};
struct
{
GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
};
struct
{
uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
};
};
ここで、すべての
GPIO_MAPx_YYY
はマクロで、次のように定義されます。
uint32_t :32
またはレジスタタイプ(専用の構造体)として定義されます。
ここでは
uint32_t :192;
であり、うまく動作しますが、警告が発生します。
これまで検討したこと
に置き換えたかもしれませんが、いくつかの
uint32_t :32;
(ここでは6個)に置き換えているかもしれませんが、極端な話、私の場合は
uint32_t :1344;
(42)のようなものもあります(中略)。だから、構造体生成がスクリプト化されているとはいえ、他の8k行の上に100行程度を追加するのは避けたい。
正確な警告メッセージは以下のようなものです。
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(いかにも怪しげな感じが好きです)。
私はむしろ ではなく の使用は、単に警告を削除することでこれを解決することができます。
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
が解決策になるかもしれません...もし私が
TheRightFlag
. しかし、指摘されているように
このスレッド
,
gcc/cp/class.c
この悲しいコード部分と
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
がないことを物語っています。
-Wxxx
フラグがないことがわかります。
どのように解決するのですか?
複数の隣接する匿名ビットフィールドを使用します。 そのため、代わりに
uint32_t :160;
といった具合に、例えば
uint32_t :32;
uint32_t :32;
uint32_t :32;
uint32_t :32;
uint32_t :32;
匿名にしたいレジスタごとに1つずつ。
埋めるべき大きなスペースがある場合、単一の32ビットスペースを繰り返すためにマクロを使用することが明確であり、エラーが発生しにくいかもしれません。 例えば、与えられた
#define REPEAT_2(a) a a
#define REPEAT_4(a) REPEAT_2(a) REPEAT_2(a)
#define REPEAT_8(a) REPEAT_4(a) REPEAT_4(a)
#define REPEAT_16(a) REPEAT_8(a) REPEAT_8(a)
#define REPEAT_32(a) REPEAT_16(a) REPEAT_16(a)
すると、1344(42×32bit)のスペースがこうして追加されます。
struct
{
...
REPEAT_32(uint32_t :32;)
REPEAT_8(uint32_t :32;)
REPEAT_2(uint32_t :32;)
...
};
関連
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] Linux上で動作するC++コードのプロファイリングを行うにはどうすればよいですか?
-
[解決済み] Androidでアプリケーションのメモリ使用量を確認するにはどうすればよいですか?
-
[解決済み】ローカル変数のメモリはスコープ外からアクセスできる?
-
[解決済み】標準ライブラリを使ってアライメントされたメモリのみを割り当てるには?
-
[解決済み】CとC++におけるユニオンの目的
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件