[解決済み] GCCの__attribute__((aligned(x)))でスタック変数がアライメントされるのか?
質問
次のようなコードがあります。
#include <stdio.h>
int
main(void)
{
float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}
そして、以下のような出力が得られます。
0x7fffbfcd2da0 0x7fffbfcd2da4 0x7fffbfcd2da8 0x7fffbfcd2dac
のアドレスはなぜ
a[0]
の倍数でないのは
0x1000
?
具体的には
__attribute__((aligned(x)))
は何をするのでしょうか?私は誤解していました。
この
の説明を誤解していませんか?
gcc 4.1.2を使っています。
どのように解決するのですか?
配列がスタック上にあることと、コンパイラが古すぎてオーバーアラインされたスタック変数をサポートしていないことが問題だと思います。 GCC 4.6 およびそれ以降 はそのバグを修正しました。 .
C11/C++11
alignas(64) float a[4];
2のべき乗のアライメントで動作します。
だから、GNU Cの
__attribute__((aligned(x)))
を使用していたように。
(C11では
#include <stdalign.h>
に対して
#define alignas _Alignas
:
cppref
).
しかし、4k ページ境界への非常に大きなアライメントのケースでは、スタック上にそれを望んでいないかもしれません。
関数の開始時にスタックポインタは何でもよいので、必要以上に多くのアロケーションを行い、それを調整することなしに配列をアライメントする方法はありません。 (コンパイラは
and rsp, -4096
またはそれと同等のものを使用して、割り当てられた 0 ~ 4088 バイトのいずれも使用しません。その領域が十分に大きいかどうかで分岐することは可能ですが、配列やその他のローカルのサイズよりもはるかに大きい巨大なアライメントは通常の場合ではないため、実行されません)。
配列を関数からグローバル変数に移動させれば、うまくいくはずです。他にできることは、ローカル変数として維持することですが (これは非常に良いことです)、それを
static
. こうすることで、スタックに格納されるのを防ぐことができます。配列のコピーは1つだけなので、これらの方法は両方ともスレッドセーフでも再帰セーフでもないことに注意してください。
このコードで
#include <stdio.h>
float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
int
main(void)
{
printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}
こんなの出るんだ。
0x804c000 0x804c004 0x804c008 0x804c00c
というのが期待されるものです。あなたのオリジナルのコードでは、私はちょうどあなたがしたようにランダムな値を取得します。
関連
-
initializer element is not constant "というエラーが表示されるのですが?
-
[解決済み] ⑭と⑯は何のためにあるのですか?
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] g++とgccの違いは何ですか?
-
[解決済み] 難読化Cコードコンテスト2006。sykes2.cの解説をお願いします。
-
[解決済み] printfにおけるdoubleの正しい書式指定子
-
[解決済み] .aファイル、.soファイルとは何ですか?
-
[解決済み】標準ライブラリを使ってアライメントされたメモリのみを割り当てるには?
-
[解決済み】スタックフレームの概念をわかりやすく説明する
-
[解決済み] 属性__((packed, aligned(4))) の意味を教えてください。"
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
解決済み] g++ コンパイルエラー: ')'トークンの前に一次式があることが予想される
-
[解決済み] mallocで文字列を確保する
-
[解決済み] Windows用Cコンパイラ?[クローズド]
-
[解決済み] CコードでEOFを表現する?
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] 配列のすべてのメンバーを同じ値で初期化するには?
-
[解決済み] while ( !feof (file) ) 」は、なぜいつも間違っているのですか?
-
[解決済み] printfにおけるdoubleの正しい書式指定子
-
[解決済み] C 言語の配列へのポインタ/ポインタの配列の曖昧さ解消
-
[解決済み] FortranはC言語よりも重い計算を最適化しやすいですか?