4

私はソケットプログラミングに取り組んでいます。私のコードは私が望むように実行され、私はそれを使用することができます。しかし、それは私にコンパイルに関する警告を与えます。

私はを使用してコンパイルします

gcc server1.c -o server1 -lpthread

そして私は警告を受け取ります

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

このエラーは、次のコードで発生します

int newsockfd;
newsockfd = (int)newsockfdd; //this line

そして、私は次のコードのチャンクでnewsockfdd(int)を使用しています

if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
    {
        perror("Thread create error");
    }

おそらくお分かりのように、コードはあまりうまく書かれていません(私はそれをより良くするために取り組んでいます)。この警告は、intのサイズに関係しているために発生することを私は知っています。しかし、私はそれを修正する方法を本当に知りません。pthread_createステートメントに(intptr_t)を挿入する前は、その行に警告が表示されていましたが、そのときの警告は

warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

これには簡単な修正があるはずですか?しかし、私はそれを見つけることができません。Ubuntu64ビットを使用しています。それが警告の理由ですか?

4

1 に答える 1

6

newsockfddコメントで確立されているように、状況は次のとおりです(渡された引数または受信されたパラメーターの混乱を避けるためのモジュロ名前変更)

void *serverThread(void *arg) {
    // ...
    int newsockfd = (int)arg;
    // ...
}

およびin main(またはそこから呼び出される関数)

// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
// ..

したがって、int newsockfddが引数として渡されるとserverThread、にキャストされvoid*ます。元々、そのキャストは直接でしたが、への中間キャストintptr_tは、に関する警告を削除するために挿入されましたcast to pointer from integer of different size

そして、serverThreadでは、受信したvoid*ものがにキャストされint、結果として。に関する警告が表示されcast from pointer to integer of different sizeます。

この警告は、に中間キャストを挿入することによっても削除できる可能性がありますintptr_t

ただし、標準では整数をポインタにキャストしたり、その逆を行ったりすることはできますが、結果は実装で定義されており、int -> void* -> intラウンドトリップが保証されるわけではありません(ただし、標準の脚注には

ポインタを整数に、または整数をポインタに変換するためのマッピング関数は、実行環境のアドレス指定構造と一貫性を保つことを目的としています。

したがって、おそらくこの場合はラウンドトリップして意図したとおりに機能しますが、aのサイズがvoid*整数型のサイズよりも小さい場合は[十分に小さい絶対値の値に対してのみ]機能しない可能性があります[ long long -> void* -> long long32ビットを考慮してくださいシステム])。

適切な修正は、整数とポインタの間のキャストを回避することです。

void *serverThread(void *arg) {
    // ... check that arg isn't NULL
    int newsockfd = *(int *)arg;
    // ...
}

severThread、受信したポインタを適切なタイプのポインタにキャストし、ポイントされた値を読み取ります。main

if// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, &newsockfdd) != 0)

のアドレスを渡しますnewsockfdd

1つの注意点:serverThread複数の場所から呼び出された場合、これらすべての場所での呼び出しを修正する必要があります。

于 2012-11-25T14:07:25.553 に答える