質問: こんにちは。 gcc (H8系) で組込向けにプログラムを作ろうとしています (gcc:8.3.0, binutils:2.32, Newlib:3.1.0)。 ビルドは出来たのですが、mapファイルを見たところ、グローバル変数が定義順に並んでいません。アセンブリコードを見たところ、定義順に記述されていたので、おそらくリンカが配置を最適化したのだと考えました。 それでは、と、リンカスクリプトで独自のセクションを用意しました。今度はバラバラの順序にはならなかったのですが、なぜか定義とは逆順に割り当てられていました。 リンカスクリプトの定義: ``` .nonvolatile : { *(.nonvolatile) } > ram ``` 変数の定義: ``` #define NV_SECT __attribute__((section(".nonvolatile"))) double a NV_SECT; unsigned int b NV_SECT; unsigned char c NV_SECT; ``` メモリ配置: ``` 0x0000000000400000 _c 0x0000000000400002 _b 0x0000000000400004 _a ``` 質問ですが、gnu ld で変数のメモリへの配置を定義順にするには、何が必要なんでしょうか? どうぞよろしくお願いします。 、、とは書いたものの、 GCC compiles EEPROM addresses in reverse order を見る限り、駄目っぽいですかね、、? いまのところ、解決策としては、 1. 構造体にまとめる: 上記サイトの解決案 2. 変数ごとに番地を指定する: 人間リンカ 3. 変数ごとにセクションを区切る: "nonvolatile.a" のように。人間リンカよりはまし。できることは確認 でしょうか。なにかうまい設定があればよいのですが、、よろしくお願いします。
回答: ウチでは [gcc](/questions/tagged/gcc "'gcc' のタグが付いた質問を表示") でなく Renesas H8 C/C++ Compiler を使っていますが 実メモリ上の配置順ってそんなに重要ですか? ウチでは H8CC/SHCC の `-stuff` コンパイルオプションを使って、定義順でなくサイズ別に変数を配置していて困ったことはありません(むしろパディングの無駄領域が排除できて万々歳っす)。定義順が重要になるとしたら通信電文を直接変数に保持したい場合くらいしか思いつかないのですが、それならば 1. の通り `struct` にしちゃうのが自然でしょう。これもバイトオーダーやビットオーダーが吸収できないとハマるのであまりお勧めできないですけど。 というわけで「なぜ」配置順を維持したいのかわからないと積極的に提案できないんですが、とりあえず 1. 以外に方法はないでしょう( 3. してもリンク時のオブジェクトファイル指定順などで順序が変わるはずなので無駄な努力っぽい) [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") の場合 `struct`/`class` のメンバ変数が宣言順に配置されることすら決まっていませんし、 ICE でメモリダンプを取って変数の値を確認するだけなら変数定義順でなくても一向にかまわないし、と難しい根拠ならいくらでも挙げられますけど、配置順にする必然は挙げにくくて提案しづらいです。