ちょうど質問を読んだところですアライメントされていないメモリアクセスは常にバスエラーを引き起こしますか? ウィキペディアの記事Segmentation Faultにリンクされています。
この記事には、あまり一般的ではないIntel プロセッサ フラグAC (Alignment Check)の素晴らしいリマインダーがあります。
そして、それを有効にする方法は次のとおりです (Wikipedia のBus Error exampleから、x86-64 System V 用に修正されたレッド ゾーン クロバー バグにより、これは Linux および MacOS で安全であり、基本的な asm から変換されますが、関数内では決して良い考えではありません: AC への変更を、メモリ アクセスに基づいて順序付けする必要があります。
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\n orl $0x40000,(%%esp)\n popf" ::: "memory");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("add $-128, %%rsp \n" // skip past the red-zone, in case there is one and the compiler has local vars there.
"pushf\n"
"orl $0x40000,(%%rsp)\n"
"popf \n"
"sub $-128, %%rsp" // and restore the stack pointer.
::: "memory"); // ordered wrt. other mem access
# endif
#endif
有効にすると、 の ARM アライメント設定と同じように機能します。アンアライメントされたメモリ アクセスをトラップする方法を/proc/cpu/alignment
参照してください。例えば。
さらに、GCC を使用している場合は、-Wcast-align
警告を有効にすることをお勧めします。厳密なアラインメント要件を持つターゲット (ARM など) 向けにビルドする場合、GCC はアラインされていないメモリ アクセスにつながる可能性のある場所を報告します。
ただし、memcpy およびその他の関数に対する libc の手書きの asm は依然として非整列アクセスを行うため、AC を設定することは x86 (x86-64 を含む) では実用的でないことが多いことに注意してください。GCC は、ソースがアラインされていなくても、アラインされていないアクセスを行う asm を出力することがあります。たとえば、隣接する 2 つの配列要素または構造体メンバーを一度にコピーまたはゼロにするための最適化としてです。