[C言語入門] 演算子の使い方(6)
高木です。こんにちは。
少し間があいてしまいましたが、前回予告したとおり、今回はsizeof演算子と_Alignof演算子について解説します。
_Alignof演算子はCの3rd Edition、すなわちC11から導入された演算子です。
それでは早速本題に入るとしましょう。
sizeof演算子と_Alignof演算子
Cのsizeof演算子と_Alignof演算子は他の演算子とはちょっと異なる特徴を持っています。
どんなところが異なるかというと、オペランドに型名を取るのです。
具体的には、sizeof(int)
や_Alignof(int)
のように、型名を丸括弧で囲んでオペランドを指定します。
オペランドに指定する型名は、関数型や不完全型であってはなりません。
sizeof演算子は、オペランドに型名だけでなく式を指定することもできます。
式を指定する場合は丸括弧は必要ありません(丸括弧で囲んでもかまいません)。
ただし、演算子の優先順位の関係で、二項または三項演算子を用いた式をオペランドに取るときは丸括弧で囲まないと意味が変わってしまいます。
たとえば、sizeof 1 + 2
のように記述すると、それは(sizeof 1) + 2
の意味になってしまいます。
期待通りの結果を得るには、sizeof (1 + 2)
とする必要があります。
_Alignof演算子のオペランドには式を指定できませんので注意してください。
sizeof演算子と_Alignof演算子の評価結果はsize_t型になります。
size_t型は<stddef.h>ヘッダで定義される型で、符合無し整数型です。
sizeof演算子は指定したオペランドのバイト数を返します。
sizeof演算子の評価結果は通常整数定数式になりますが、オペランドに可変長配列を指定した場合はその限りではありません。
C言語でいう1バイトというのはchar型のサイズのことで、1バイトが何ビットで構成されるかは<limits.h>ヘッダで定義されるCHAR_BIT
マクロを調べる必要があります。
1バイトのビット数は通常は8ですが、16や32、あるいはそれ以上のことも実際にあります。
_Alignof演算子は指定したオペランドの境界調整数を返します。
オペランドに配列を指定した場合、評価結果はその配列の要素の境界調整数になります。
_Alignof演算子の評価結果は整数定数式になります。
多くのコンピュータでは、メモリに対してデータを読み書きするには、データが配置されているアドレスに制約がある場合があります。
たとえば、16ビット以上のコンピュータでは、16ビットのデータは偶数のアドレスに配置されていなければならないケースがほとんどです。
奇数のアドレスに配置されていても読み書きはできるアーキテクチャもありますが、効率が悪くなります。
同様に、32ビット以上のコンピュータでは、32ビットのデータは4の倍数のアドレスに配置されていなければならない、あるいは効率を考慮してそれが望ましい設計になっています。
このように、偶数アドレス(2の倍数アドレス)や4の倍数アドレスなどに配置されていなければならない場合、2や4を境界調整数と呼びます。
_Alignof演算子はこの境界調整数を調べるための演算子です。
<stdalign.h>ヘッダではalignof
マクロが定義されます。
alignof
マクロは_Alignof
に展開されます。
C言語がバージョンアップするとき、新しいキーワードが導入されることがあります。
既存のソースコードに悪影響を与えることがないよう、下線で始まり大文字が続くキーワードが採用されます。
_Alignofもそうですね。
このように、下線で始まり大文字が続く名前は予約済み識別子であり、処理系に予約されているのでユーザーが使用することはできません。
インクルードガードのマクロや構造体などのタグ名に、このような予約済み識別子を使っているソースコードをよく見かけますが、明らかな間違いなので是正すべきです。
というわけで、今回はsizeof演算子と_Alignof演算子を解説しました。
次回はキャスト演算子と、それに関連して型変換全般を解説できればと考えています。