質問: strdup("\0a\0\0\0\0\0\0"); if (!((uintptr_t)s % 8)) s++; printf("%lu\n", *(uint64_t *)s); } ``` 実行環境は下記の通りです CPU ryzen 5 3600 OS windows10 64bit上のvirtual boxでUbuntu 18.04.5 LTSを起動 コンパイラ clang オプション -Werror -Wall -Wextra
回答: インテルx86/x64アーキテクチャのCPUには(一部の命令/データ以外では)個々のメモリアクセスでのアライメント制約は無いですよ。 x86 - データ構造アライメント - Wikipedia > > x86アーキテクチャは本来、アライメントされたメモリアクセスを必要とせず、またそれなしでは動作するが、x86 CPUのSSE2命令の中には、データを128ビット(16バイト)にアライメントさせる必要があるものがあり、これらのアーキテクチャでアライメントされたデータを使用することにより、パフォーマンス上の大きな利点が得られる。ただし、MOVDQUなどのアラインされていないアクセスのための命令もある。さらに、ロードとストアの操作は、通常、正しくアラインされていればアトミックである。 > > > 3.1 アラインメントに寛容な CPU の場合 (alignment-tolerant processors) - データ型のアラインメントとは何か,なぜ必要なのか? > > このようなXを読み書きするように命令された CPU はどうするだろうか? 「2回に分けて読み書きする」と思うだろう.x86 は実際そのように動作する (ただし後述する場合を除く). > > > 3.2 アラインメントに厳格な CPU の場合 (alignment-strict processors) - データ型のアラインメントとは何か,なぜ必要なのか? > > x86 以外の多くの CPU (特に RISC) は上記のようには動作せず,エラーとして処理する. つまり「不正アラインメント例外注3」を発生させる. > > > 大部分のアクセスでは、多少アドレスをずらしても、そこからuint64_tのサイズ分が全て読み取り有効な領域に収まっていれば(ページメモリ境界ギリギリとかでなければ)、例外は発生しないでしょう。 ちなみに、以下の部分は`アライメントを意図的にずらす`処理としては不適切では? 丁度8バイト境界の時には`s++`の処理は実行されないように見えます。 元々8バイト境界に収まっていない時だけ`s++`が実行されるように見えます。 ``` if ((uintptr_t)s % 8) s++; ```