こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語のvoid型ポインタ変数について。

C言語のvoid型ポインタ変数について。

C言語のvoid型ポインタ変数について質問があります。

組み込み系の開発を行っているのですが、現在使用しているシステムで、
提供されている "API" を介してアプリケーション部のソフト作成を行っています。

この "API" ですが、引数の多くはvoid型ポインタとなっています。

ある人がこの引数がvoid型となっているのを見て、
『なんでvoid型なんや??、C言語でアセンブラと違うんやから、void型なんかにしない方が良い』
とおっしゃいました。
この意味がよくわからなかったのですが、なぜ void型はよろしくないんでしょうか?

--
僕が思うに、APIなんやから引数を void型ポインタ にすることでどんな型にも対応できる
汎用的であると感じ、逆にこの方が良いのではと感じたのですが。。


-API例----
int _exApiKannsuu( char in_data, void* out_data )

"in_data" をもとに "out_data" を取得する。
どーやらこの "out_data" が void型 であるのががよくないらしい・・

投稿日時 - 2008-01-14 22:07:56

QNo.3680440

困ってます

質問者が選んだベストアンサー

同じ関数で 複数の型のデータを扱うのでなければ特定の型のポインタにしたほうが良いでしょう

このAPI宣言だけみた使用者は 何型のポインタを渡せば良いのかわかりません

char*で良いのか int*が必要なのかはたまた何かの構造体のポインタを要求しているのか ・・・

投稿日時 - 2008-01-14 22:18:49

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

>int _exApiKannsuu( char in_data, void* out_data )
他の方も指摘されていますが、この関数がin_dataを元に
何を行ってout_dataに何を返すのかがわかりません。

それにout_dataに何を指定すればいいのか、どのくらいのサイズが
必要なのかもわかりません。どんな型にも対応できるということは、
どんな型を渡せばよいか分からないということでもあります。

逆にこの関数を作った人も、out_dataがどこまで書き込めるのか、
などが判りづらくなり、特定の決まったもの処理して返すならば、
out_dataのサイズを渡すかそのサイズ分の領域がわかるような引数を
取るべきだと思います。

どんなものにも例外はあると思いますが、今回であれば
該当の関数が与えられる引数の型に依存しない処理を行うのであれば
void*型でも良いと思います。(その場合はその領域のサイズを指定させるなどが良く行われると思いますが)

投稿日時 - 2008-01-15 10:52:44

ANo.4

> 僕が思うに、APIなんやから引数を void型ポインタ にすることでどんな型にも対応できる
> 汎用的であると感じ、逆にこの方が良いのではと感じたのですが。。

その論法からすれば、関数原型を止めてしまうか、第2引数以降を可変個引数にした方が汎用性が高まるはずです。
しかし、実際にはそんなことはありません。

void*をint*や構造体型*のようにしても、(C++ではないので)コンパイル時にエラーを検出できるわけではありませんが、警告ぐらいは出ることを期待できます。
ただし、(memcpyのように)具体的な型情報が必要ない場合には、void*の方がよいでしょう。

それに_exApiKannsuuという関数名がよくありません。この名前を見ても、何をする関数なのかさっぱり分かりません。当然、各引数に何を渡せばよいのかも想像がつきません。また、下線から始まる外部識別子は予約済み識別子であり、こんな関数名では動作が未定義になります。さらに、Kannsuuというのは「関数」の意味のローマ字表記だと思いますがスペルが間違っています。
こうした状況を考えると設計も実装も非常に怪しく、すべてに対して疑ってかかりたくなる気持ちも十分理解できます。

投稿日時 - 2008-01-15 07:26:32

ANo.3

「void型ポインタ にすることでどんな型にも対応できる」ので、
うっかり間違ってもコンパイル時にエラーとなってくれません。

/* 文字列の長さを返す関数があったとしよう */
int stringLength(void* str); /* strは文字列であるべし! */

int n;
int length = stringLength(&n); /* エラーにしてくれない */

投稿日時 - 2008-01-14 22:35:13

ANo.2

あなたの意見の通りだと思います。
本来はある人の意見のように、全ての型の引数を用意し、同じ関数名で関数定義すべきなのかもしれません。しかし、その組合せが組合せの爆発を起こすと、そうも言っていられないでしょう。なので、あるシリーズの関数群の引数は、違う型の可能性のあるものはvoidポインタで統一する、というのはありだと思います。

投稿日時 - 2008-01-14 22:20:08

あなたにオススメの質問