size_t
読み:サイズ-アンダースコア-ティー
外語:size_t
C/C++などにおける変数型の一つ。「長さ」を格納するために使われる。Cの場合はANSI C以降で対応する。
書式
C
#include <stddef.h>
定義は後述。
C++
C++では、std::size_tである。
#include <cstddef>
namespace std {
typedef 処理系依存 size_t;
}
定義は後述。
概要
size_tの大きさは環境依存である。
「長さ」といった曖昧で環境依存しそうなものを、何も考えずintで済ませてしまうことを避けるため、このような型が作られた。
例えば、strlen関数や、sizeofなどは返却値がsize_tである。
なお、size_tはプリミティブ型ではなく、typedefである。また、size_t型の扱う値は常に0以上の整数である。
特徴
C
C99(ISO/IEC 9899:1999)においては、ある変数をsize_t型で宣言するためには次のいずれかの標準ヘッダーを読み込む必要があるとしている。
- stddef.h
- stdio.h
- stdlib.h
- string.h
- time.h
- wchar.h
実際の定義はstddef.hの中にあることが多い(実装による)。他のヘッダーファイルは、間接的にstddef.hをincludeしている。
C++
C++でも、ヘッダーのincludeが必要で、その仕様はCと変わらない。
C++の場合は先頭にcを付けて後尾に.hを付けない、<cstddef>を使用する。両者の違いは名前空間(namespace)である。
- cstddef
- cstdio
- cstdlib
- cstring
- ctime
- cwchar
理論上は、この何れかをincludeすれば、size_tがtypedefされる。
規格によれば、JIS X 3014「プログラム言語C++」p258には以下のように書かれている。
17.4.3.1.4 型 Tを標準Cライブラリ内の型とするとき, ::T及びstd::Tは, 処理系用に予約する。::Tが定義されている場合, std::Tと同一とする。
簡単には、C++では、::size_tとしてもstd::size_tとしても使えるということである。同様の例には、ptrdiff_t、FILEといったものもある。
サフィックス
数値の型を表わすサフィックスは、特に定義されていない。
printf
printfののフォーマット文字列では、C99以降では長さとしてzを使う(例えば%zu)。
定義
ユーザー空間
gcc 4.4
ユーザー空間(glibc)の場合、例えばx86の64ビットの場合で、GCC 4.4なら /usr/lib/gcc/x86_64-linux-gnu/4.4/include/stddef.h で定義される。
#define __SIZE_TYPE__ long unsigned int
typedef __SIZE_TYPE__ size_t;
様々な環境に対応できるよう大量の#ifndefの中に埋もれているが、特に特殊な定義がない場合、x86の64ビットでは間接的にlong unsigned intつまりunsigned longで定義されている。
Windows
Microsoft WindowsのVisual C++では、次のようになっている。
つまりWin32環境では32ビット長、Win64環境では64ビット長である。
カーネル空間
FreeBSD
stddef.hなど
typedef __size_t size_t;
32ビットの場合、/usr/include/asm/_types.h など
typedef unsigned int __uint32_t;
typedef __uint32_t __size_t;
x86の64ビット(AMD64 ISA/Intel 64)の場合、/usr/include/machine/_types.h など
typedef unsigned long __uint64_t;
typedef __uint64_t __size_t;
つまりFreeBSDでは、概ね、32ビット環境ではunsigned int、64ビット環境ではunsigned longで間接的に定義されるようになっている。
Linux
Linuxカーネルでは、次のようにして使う。
#inlude <linux/types.h>
include/linux/types.h では次のように定義される。
typedef __kernel_size_t size_t;
__kernel_size_tの定義は環境ごとに様々であるが、代表的な環境(x86とARM)では次のようになっている。
x86の32ビットの場合、arch/x86/include/asm/posix_types_32.h で定義される。
typedef unsigned int __kernel_size_t;
x86の64ビットの場合、arch/x86/include/asm/posix_types_64.h で定義される。
typedef unsigned long __kernel_size_t;
ARMの32ビットの場合、arch/arm/include/asm/posix_types.h で定義される。
typedef unsigned int __kernel_size_t;
概ね、32ビットならunsigned int、64ビットならunsigned longで定義されている。その目的から、概ねアドレス長程度の長さが定義されると思われる。
再検索