Sizeof

主にCとC++において、codice_1は、データ型の大きさを求める単項の演算子である。codice_1は原則としてコンパイル時計算される演算子で、式もしくは括弧でくくった型指定子を与えるとその大きさをバイト単位で返す。これは組み込みの数値型（整数型や浮動小数点数型）、列挙型、ポインタ型、利用者定義の複合データ型（構造体、共用体、C++のクラス）まで、ほぼ全てのデータ型に対して使用できる。
必要性.
多くのプログラムで、データ型の大きさがわかると便利な状況がある。最もよくある例としては標準Cライブラリのcodice_3などによる動的メモリ確保が挙げられる。組込型の大きさは処理系定義となっており、厳密な大きさはcodice_4がcodice_5であることを除いて標準に定められていない。次の例では10個の要素を持つcodice_6型の配列を格納するのに十分なメモリを確保しようとしている。（処理系に依存したコードを書くつもりでなければ）codice_6型の正確な大きさはわからないのでcodice_1が必要となる。
int *pointer; /* intへのポインタ型、メモリ確保したデータを参照する */
pointer = malloc(sizeof (int) * 10);
このコードで、codice_3は確保したメモリ領域へのポインタを返すが、その大きさはちょうどcodice_6型10個分になる。
一般的に、CとC++で型の大きさを仮定するのは安全でない。標準規格でもcodice_11以外の型がメモリ上で何バイト占めるかを規定していない。たとえば、16ビットシステムでのcodice_6型の大きさは通例2バイトであるが、大半の32ビットシステムではcodice_6型の大きさは4バイトである。また、構造体や共用体ではアライメントもあり、ますます正確な大きさを求めるのは困難となる。そのようなこともあり、移植性の高いプログラムを書くには型の大きさを求めるためにcodice_1を使用することが推奨されている。
CとC++.
使用方法.
codice_1演算子は、メモリ上に領域を占めるものであれば、ほとんどどんなものに対しても使用できる。codice_1を使うには、キーワードcodice_1の後に変数や式あるいは括弧でくくった上で型名を書く。変数や式の場合は、括弧でくくるかどうかは自由である。次の例ではcodice_6型がcodice_11型の4倍のサイズを持つ実装の場合、codice_20と出力される（なお、codice_11型にcodice_1演算子を適用した結果は全ての実装においてcodice_5でなければならない）。
// C99
char c;
printf("%zu, %zu", sizeof c, sizeof (int));
// Microsoft Visual C++
char c;
printf("%Iu, %Iu", sizeof c, sizeof (int));
// キャスト
char c;
printf("%lu, %lu", (unsigned long) sizeof c, (unsigned long) sizeof (int));
codice_1の結果は実装定義の符号無し整数型であるcodice_25型となり、負数になることはない。
codice_1を関数型、ビットフィールド、不完全型（後述）に対して使用することはできない。
なお、codice_27などでcodice_25型を書式出力する場合、C99で追加された長さ修飾子codice_29を用いる。
C99に対応していない処理系では、引数をキャストするか、処理系依存の修飾子（たとえばMicrosoft Visual C++ならば修飾子codice_30）を用いる。
もしcodice_31を使用すると、codice_25型とcodice_33型のサイズが異なる環境において未定義動作となる。
配列に対するsizeof.
codice_1が配列型に使用されると、その配列がメモリ上に占める大きさが演算結果となる。配列の大きさは、要素の型の大きさに要素数をかけた値と規定されており、例えば要素型codice_35についてcodice_36はcodice_37と同じ値になる。逆に、配列codice_38に対して、codice_39の演算により、配列の要素数を求めることが可能である。
次の例では、文字の複写時にバッファオーバーランを起こさないよう、codice_1を配列の大きさを求めるために用いている。
/* sizeofを配列に使用する例 */
int main(void)
 char buffer[10]; /* 要素数10のchar配列 */
 /* 標準入力から読み取った結果をbufferへ9文字までのみ複写する。
 *（sizeof (char)は常に1なので、sizeof buffer[0]で割る必要はない）
 fgets(buffer, sizeof buffer, stdin);
 puts(buffer);
 return 0;
C99で可変長配列に対して codice_1を適用する場合、配列の大きさは実行時に動的に計算され、コンパイル時定数にはならない。
sizeofと不完全型.
codice_1は完全に定義されたデータ型（メモリレイアウトが確定した型）のみに適用できる。配列なら、要素数が変数宣言に含まれていなければならず、構造体や共用体ならメンバが完全に定義されていなければならない。例えば次の二つのソースファイルがあったとする。
/* file1.c */
int arr[10];
struct x { int one; int two; };
/* file2.c */
extern int arr[];
struct x;
どちらのファイルも正しいCのソースであるものの、"file1.c"ではcodice_1をcodice_44とcodice_45に使用できるが、"file2.c"では完全型でないため使用できない。"file2.c"ではcodice_44の要素数がわからず、codice_45のメンバも分からないためである。"file2.c"でcodice_44とcodice_45をcodice_1で使用できるようにするには、"file2.c"のcodice_44の宣言に要素数を指定したり、codice_45の完全な宣言を書いたりする必要がある。
構造体メンバのsizeof.
構造体やクラスの非静的メンバに対してcodice_1を適用する場合、CおよびC++03規格までのC++では、構造体やクラスのオブジェクト（インスタンス）からメンバにアクセスする式に対して適用しなければならない。
struct my_type {
 int member1;
 short member2;
int main(void) {
 struct my_type obj;
 printf("%u\n", (unsigned)sizeof(obj.member1));
 printf("%u\n", (unsigned)sizeof(obj.member2));
 /* sizeofはコンパイル時に評価されるので、以下のように書いても実行時のNULLデリファレンスは発生しない */
 printf("%u\n", (unsigned)sizeof(((struct my_type*)NULL)->member1));
 printf("%u\n", (unsigned)sizeof(((struct my_type*)NULL)->member2));
 return 0;
C++11規格以降では、スコープ解決演算子codice_54を利用して以下のように書けるようになった。
struct my_type {
 int member1;
 short member2;
int main() {
 printf("%zu\n", sizeof(my_type::member1));
 printf("%zu\n", sizeof(my_type::member2));
GCCなど、一部のコンパイラでは、C++03以前でもこの記法を拡張としてサポートしていた。
実装.
コンパイラは言語の実装に適合するように、codice_1演算子をデータ型のメモリ上に占める大きさを結果とするように実装しなければならない。また（既述の例外を除いて）これはコンパイル時計算される演算子であり、アセンブリ言語上では単なる即値になる。
構造体のパディング.
利用者定義型の大きさはアライメントのためにメンバの大きさの合計よりも大きくなることが規格では許されている。次のコードは多くの環境においてcodice_56と出力される。
struct student {
 char grade; /* charは1バイト */
 int age /* intは4バイト */
printf("%zu", sizeof (struct student));
この理由は、多くのコンパイラでは通常ワード単位にデータを揃えるためであり、個々のメンバも境界を揃えられる。上の場合は、境界調整によってメンバ変数のcodice_57が次のワード単位に置かれる。このような構造体には境界調整のためにメンバ間やメンバの後ろに「パディング」と呼ばれる余分な隙間が置かれる。多くのCPUではデータがワード単位のメモリアドレスに置かれていた方が高速に読み書きでき、また中にはワード単位に揃えられていないと読み書きできないCPUもある。
D.
D言語では全ての型が持っているプロパティとしてcodice_1が用意されている。
void main()
 writefln(int.sizeof);
.NET.
.NET Framework/.NET Coreでは、codice_59メソッドによってオブジェクトのアンマネージサイズやアンマネージ型のサイズをバイト単位で取得可能である。.NET 4.5.1でジェネリックバージョンのオーバーロードが追加された。そのほか、各.NET言語に類似の組み込み言語機能が用意されていることがあるが、codice_60型に対する演算結果など、必ずしもcodice_59と同じ結果になるとは限らない。
C++/CLI.
C++/CLIのcodice_1演算子はネイティブ型（基本型およびポインタ型）に用いる限りコンパイル時定数となり、基本的にC++と同じである。しかし値クラス (codice_63) 型、（マネージ）ハンドル型やジェネリック型引数に対して用いられたときにはコンパイル時定数でなくなる。また参照クラス (codice_64) 型やインターフェイス型に対して用いることはできない（不正となる）。
C#.
C#のcodice_1演算子は、アンマネージ型（組み込み型、列挙型、ポインタ型、参照型のフィールドやプロパティを含まないユーザー定義の構造体）のサイズをバイト単位で取得する。結果はcodice_6型となる。特定の組み込み型に対してcodice_1演算子を用いた場合の結果はコンパイル時定数となるが、それ以外の型に使用した場合はコンパイル時定数とならない。また、codice_1演算子を使用するにはunsafeモードが必要だが、C# 2.0以降は組み込み型に対するcodice_1に関してのみunsafeが不要となった。
Visual Basic.
Visual Basicでは、codice_70関数などが存在する。codice_70は文字列を引数に与えると文字列の長さを返すが、その他の型の変数を与えると変数の大きさを返す。
ActiveBasic.
ActiveBasicでは、Visual Basicと同様のcodice_70組込関数を持っているほか、codice_73組込関数を持っている。codice_70は型名を指定することができないが、codice_73は型名を指定できる。逆にcodice_73に変数や式を指定することはできない。