#author("2025-10-28T10:20:21+09:00","default:guest","guest") #author("2025-10-28T10:21:39+09:00","default:guest","guest") *参照元 [#u2248d71] #backlinks *説明 [#mf644141] -パス: [[linux-5.15/include/linux/kernel.h]] -ポインタが指す構造体のメンバ、それを含む構造体へのポインタを返す。 --例えば、 struct example { int mem_a; char mem_b; }; struct example hoge; --このような構造体があったとき、 int *mem_ptr = &hoge.mem_a; --構造体のメンバへのポインタmem_ptrしか分からない状態からhogeへのポインタを得たいときにcontainer_ofを使う。 struct example *ptr = container_of(mem_ptr, struct example, mem_a); --するとptrが指す先(hoge.mem_a)を含む構造体へのポインタ(&hoge)が得られる。 **引数 [#b71627a5] -ptr --構造体のメンバへのポインタを指定する。 -type --ptr に指定したポインタが指すメンバ、これを含む「構造体名」を指定する。マクロはここで指定した型のポインタを返す。 --ptrに指定したポインタが指すメンバ、これを含む「構造体名」を指定する。マクロはここで指定した型のポインタを返す。 ---上記の例で言うと変数名のhogeではなくて、変数の型の名前struct exampleを指定する。 -member --ptrに指定したポインタが指す「メンバ名」を指定する。 --typeに指定した型はmemberに指定した名前のメンバを持っていないとコンパイルエラーになる。 ---上記の例で言うとポインタ変数mem_ptrではなく、struct example 構造体のメンバ名であるmem_aを指定する。 ---上記の例で言うとポインタ変数mem_ptrではなく、struct example構造体のメンバ名であるmem_aを指定する。 **返り値 [#q3834c46] -type * --指定した構造体のメンバへのポインタ(ptrに指定する)が指すメンバ(メンバの名前はmemberに指定する)、これを含む構造体(構造体の型はtypeに指定する)へのポインタを返す。 --例えばlist_entry(a, struct hogehoge, b) とすれば、struct hogehoge *が返ってくる。 **参考 [#na45adb3] *実装 [#v092b33c] /** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \ -ポインタ演算のためvoid *型の__mptrに変換する。 BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ !__same_type(*(ptr), void), \ "pointer type mismatch in container_of()"); \ -ptrは、typeのmemberのポインタ型か、void *である必要がある。そうでなければビルドエラーにする。 --[[linux-5.15/BUILD_BUG_ON_MSG()]] --[[linux-5.15/__same_type()]] ((type *)(__mptr - offsetof(type, member))); }) -構造体の先頭へのポインタを計算する。この値がマクロの戻り値となる。 --member を指すポインタから、メンバーのオフセットを引く。 メンバーのオフセットは構造体の先頭から、メンバーまでの距離なので、 メンバーのポインタから引いてやれば、構造体の先頭を指すポインタが得られる。 --memberを指すポインタから、メンバーのオフセットを引く。 メンバーのオフセットは構造体の先頭から、メンバーまでの距離なので、メンバーのポインタから引いてやれば、構造体の先頭を指すポインタが得られる。 return -> ---- ---- mem_a | ---- | offset mem_b ___| ---- <- __mptr mem_c ---- ---offsetof マクロは構造体のメンバー(member)が構造体(type)の先頭から どの位置にいるか(オフセット)をバイト数で返す。 ---拡張構文ではなく C の標準的なマクロで、stddef.h で定義されている。 manpage offsetof(3) などを参照のこと。 ---offsetofマクロは構造体のメンバー(member)が構造体(type)の先頭からどの位置にいるか(オフセット)をバイト数で返す。 ---GCC拡張構文ではなく、stddef.hで定義されているCの標準的なマクロ。manpage offsetof(3) などを参照のこと。 *コメント [#g88406c7]