ショッピングモール  


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.3133

memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---Bucker(2004/12/01 23:16:29)


linux(gcc)環境でネットワークプログラミングを勉強しています。
早速ですが、質問させていただきます。
ネットワーク関連のソースを読んでいると、以下のようなものをよく見掛けるのですが、

struct sockaddr_in server;

memset( (char *)&server, 0, sizeof(srver));

memset()関数のプロトタイプは、第一引数はvoid型のポインタになっているのですが、上のようにchar型のポインタにキャストしている理由を以下のように自分は捉えているのですが、間違いがあればご指摘ください。

memset()関数はsizeof(server)の大きさだけ、0でserver構造体を埋めるが、memset()関数の第一引数で、server構造体のアドレスを得るが、そのポイントしているのはこの場合char型であると指示するため、char型でキャストしている。

と、解釈しています。(文章がヘタで、分かり難い説明かもしれません、、)
ところで、以下のようにすると

memset( (int *)&server, 0, sizeof(server));

int型が4byteの環境だとすると、struct sockaddr_in構造体の大きさは、16byteなので、ポインタを4byteずつ4回進めながら0で構造体を埋めるのでしょうか?


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味 3135 ぽこ 2004/12/01 23:55:25
<子記事> Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味 3144 Hermit 2004/12/02 09:41:16


No.3135

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---ぽこ(2004/12/01 23:55:25)


>linux(gcc)環境でネットワークプログラミングを勉強しています。
>早速ですが、質問させていただきます。
>ネットワーク関連のソースを読んでいると、以下のようなものをよく見掛けるのですが、
>
>struct sockaddr_in server;
>
>memset( (char *)&server, 0, sizeof(srver));
>
>memset()関数のプロトタイプは、第一引数はvoid型のポインタになっているのですが、上のようにchar型のポインタにキャストしている理由を以下のように自分は捉えているのですが、間違いがあればご指摘ください。

私は過去との互換性を取るために明示的にキャストしているのではないかと
思います。
手元に何の資料もないのでわからないのですが、void*という概念は
初期のCにはなかったのでは?
memsetの第1引数がchar*型だった時期、もしくはメジャーな実装が
過去に存在したため、明示的にchar*にキャストすることで
互換性を保とうとしたのではないでしょうか。。

#あくまで"想像"です(-_-;)



この投稿にコメントする

削除パスワード

No.3137

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---Bucker(2004/12/02 00:22:41)


>手元に何の資料もないのでわからないのですが、void*という概念は
>初期のCにはなかったのでは?
そう言われてみればそうですね。私も指摘されたことから想像で考えたのですが、memset()の第二引数が例えば、int型、もしくはdouble型など、色々な型に対応させるため第一引数はvoid型のポインタになってるのでは、とか思いました。そういう考え方をするなら以下のようにすればいいように思いますが、、、、

memset( (struct sock_addr *)&server, 0, sizeof(server));


この投稿にコメントする

削除パスワード

No.3138

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---RAPT(2004/12/02 00:35:50)


ぽこさんの考え方で合っていると思います。
もしくは、作者が古いCの仕様で凝り固まっているとか。
(古いCでは、void* がなく、char* でキャストする事で
 サイズを統一していたという話をきいたことがあります。
 charに限り、1バイトと言語規約で定まっていたため。)

> memset()の第二引数が例えば、int型、もしくはdouble型など、
> 色々な型に対応させるため第一引数はvoid型のポインタになってるのでは
第二引数は、int型であって、double型はありえません。

現行のCでは、void* 型はあらゆる型のポインタを受ける事ができますが、
古いCでは、char* 型で受けていたその理由としては、ポインタで渡された
場合、そのサイズは渡された先では分からないということはご存知ですよね?

char型は環境により、unsignedだったりsignedだったりするので、
セットする値を0〜255まで指定できるように、int型にしたのか、
'a'と記述した時、int型だからなのかは、分かりませんが。

> そういう考え方をするなら以下のようにすればいいように思いますが
> memset( (struct sock_addr *)&server, 0, sizeof(server));
&server の型は(struct sock_addr *)なので、無意味なキャストです。
「第1引数で指定した場所に1バイトずつ
 第2引数で指定した値で
 第3引数分だけセットする。」
処理えお正しく行なうための対策だったのではないかと思われます。



この投稿にコメントする

削除パスワード

No.3141

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---Bucker(2004/12/02 00:48:11)


>第二引数は、int型であって、double型はありえません。
そうでした。プロトタイプはintでした。おはずかしい。
>ポインタで渡された場合、そのサイズは渡された先では分からないということはご存知ですよね?
はい、それは知っております。
>&server の型は(struct sock_addr *)なので、無意味なキャストです。
あーほんとですね。無意味です。ホントおはずかしい。
>「第1引数で指定した場所に1バイトずつ
> 第2引数で指定した値で
> 第3引数分だけセットする。」
>処理えお正しく行なうための対策だったのではないかと思われます。
やっぱりそういう事だったんですかね。ありがとうございました。曖昧な考え方が整理できました。


この投稿にコメントする

削除パスワード

No.3139

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---RiSK(2004/12/02 00:41:51)


>>手元に何の資料もないのでわからないのですが、void*という概念は
>>初期のCにはなかったのでは?

以前 void* はありませんでした。char* がその役割をしていたようです。

>そう言われてみればそうですね。私も指摘されたことから想像で考えたのですが、memset()の第二引数が例えば、int型、もしくはdouble型など、色々な型に対応させるため第一引数はvoid型のポインタになってるのでは、とか思いました。

その通りです。

> そういう考え方をするなら以下のようにすればいいように思いますが、、、、
>
>memset( (struct sock_addr *)&server, 0, sizeof(server));

struct sock_addr * でキャストする必要はありません。
非関数ポインタは、内部表現を失うことなく void* に暗黙のうちに変換できるので,不要(と最近ここで教えてもらった)。
# それに struct sock_addr * 型を struct sock_addr * 型 でキャストするのは無駄ですよね。

int * や char * でキャストすると,処理系によっては
ポインタの情報が失われるおそれがあります。危険です。
void* なら安心です。


で最初に戻りますが,

>int型が4byteの環境だとすると、struct sockaddr_in構造体の大きさは、
>16byteなので、ポインタを4byteずつ4回進めながら0で構造体を埋めるのでしょうか?

難しいことをゴチャゴチャ考える必要は無いと思います。
sizeof(server) を引数で渡しているのですから,
sizeof(server) だけ 0 が埋められます。
# ポインタがどこを指しているかが重要であって,ポインタの型は重要ではない。


この投稿にコメントする

削除パスワード

No.3140

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---RiSK(2004/12/02 00:46:21)


RAPT さんとカブってますな…

>>そう言われてみればそうですね。私も指摘されたことから想像で考えたのですが、memset()の第二引数が例えば、int型、もしくはdouble型など、色々な型に対応させるため第一引数はvoid型のポインタになってるのでは、とか思いました。
>
>その通りです。

「第二引数」が「第一引数」の誤りであるなら,「その通りです。」


この投稿にコメントする

削除パスワード

No.3144

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---Hermit(2004/12/02 09:41:16)


K&R1st と、ANSI の間の preANSI の時代は、
ANSI に合わせようとしたため、ヘッダをいじっていたことが多かったので
多分、その時代のヘッダを使ったか、その頃の名残を尾に引いた人が書いたソースでしょう。

void * が無い場合、char * が、動作的に一番近かったので、
char * にすることがおおかったので。


この投稿にコメントする

削除パスワード

No.3145

Re:memset( (char *)&server, 0, sizeof(server));の第一引数のキャストの意味
投稿者---Bucker(2004/12/02 11:27:19)


>void * が無い場合、char * が、動作的に一番近かったので、
>char * にすることがおおかったので。
そうだったんですか。それじゃ今はもう特にキャストしてやる必要はないんですね。ありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity