備忘録とか日常とか

学んだこととかを書きます。

汎用ポインタ( Void * )によるキャストについて【C/C++】

汎用ポインタと呼ばれる(Void *)の用途について調べたのでメモする。(主にC言語としての用途)

任意のポインタを受けるため

これがほぼ全てだと思うが、(Void *)でキャストすれば任意のポインタを受け取り、変数に格納することができる。
型を指定せずに関数の引数として受ける際によく使われるっぽい。

void test(const void * number){
    const int * a = (int *) number;
}

でもこう書くと実質型チェックがなくなるわけだから、信頼性とか可読性の観点から言うと望ましくないような気がする・・・
現場でどれくらい使われているかは疑問です。

汎用ポインタ型はキャストしないと参照できないので注意。

共通データ型→汎用ポインタ→任意の型 変換

様々なコンポーネントで使用する共通のデータ型を定義しておき、各処理の中で好きな型に変換して利用することで、
構造体の参照渡しを統一的に表現する(?)ような使い方を見た。

typedef struct CommonInst {  /* 共通データ型を用意 */
   const void  *SomeData;  
}ST_ComInst;

typedef struct A_Struct {  /* FuncAの機能用構造体 */
  int  hoge1;
  int  hoge2;
}ST_A;

void FuncA(const ST_ComInst *Instance) {   /* 共通データ型のポインタを受け取り、Void型をかませて任意のポインタにキャストして使用 */
	const  ST_A *A_Inst= (const ST_ComInst_t *)(const Void *)Instance;
}

みたいな。
変数のスコープをうまく管理できればgetter/setterみたいなことも実現でき、オブジェクト指向ちっくにかける、と思う。
直接キャストすると何か不都合があるのだろうか。警告とか出るのかな?ちょっと不明。

mallocの戻り値

mallocの戻り値は汎用ポインタなので、なんにでもキャストできる。
キャストしない場合は汎用ポインタの変数を使用する必要があるのだろう。そんなことしないような気もするけど。


まとめると

  • 任意の型からアドレスを受け取れる(参照渡し引数に使える)
  • 何かにキャストしないと参照できない
  • 型変換の間にかませる

といった用途になるか。