1

私のコード

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

void * thread_func1(void *args)
{
    printf("thread 1 returning\n");
    return ((void *)1);
}

void * thread_func2(void *args)
{
    printf("thread 2 exiting\n");
    pthread_exit((void *)2);
}

int main(void)
{
    int err;
    pthread_t tid1, tid2;
    void *tret;

    err = pthread_create(&tid1, NULL, thread_func1, NULL);
    if(err)
    {
        printf("cannot create thread 1\n");
    }
    err = pthread_create(&tid2, NULL, thread_func2, NULL);
    if(err)
    {
        printf("cannot create thread 2\n");
    }

    err = pthread_join(tid1, &tret);
    if(err)
    {
        printf("thread 1 join error\n");
    }
    printf("thread 1 return code:%d\n", (int)tret);

    err = pthread_join(tid2, &tret);
    if(err)
    {
        printf("cannot join thread 2\n");
    }
    printf("thread 2 return code:%d\n", (int)tret);
    exit(0);
}

コードをコンパイルすると、次の 2 つの警告が表示されます。

join.c:44: warning: cast from pointer to integer of different size
join.c:51: warning: cast from pointer to integer of different size

のマニュアルページを読みましたpthread_join

 int pthread_join(pthread_t thread, void **retval);
   If retval is not NULL, then pthread_join() copies the exit status of
   the target thread (i.e., the value that the target thread supplied to
   pthread_exit(3)) into the location pointed to by *retval.  If the
   target thread was canceled, then PTHREAD_CANCELED is placed in
   *retval.

私の理解によると、存在ステータス(int型)はtret私のコードに格納されているので、(int)に変換するために使用しvoid *ますintが、上記の警告はスローされます。だから、私の質問は次のとおりです。

警告をクリアするためにコードを変更するにはどうすればよいですか?

4

3 に答える 3

3

これらの警告は (この場合) 無害であり、安全に無視できます。

警告は、これらの行のキャストから来ています。

printf("thread 1 return code:%d\n", (int)tret);  // line 44
...
printf("thread 2 return code:%d\n", (int)tret);  // line 51

コンパイラは、ポインター (64 ビットの可能性があります) をより小さな 32 ビット整数にキャストしていると不平を言っています。従来の C コードの多くは、さまざまな理由から、ポインターと整数の間を行ったり来たりするのが好きです。昔は、ポインタは整数と同じサイズだったので、これで問題ありませんでした。しかし、64 ビット ターゲットがより一般的になったとき、これは突然危険になりました。アドレス 0x00000000'ffffffff の上を指す 64 ビット ポインターがある場合、整数にキャストするときに上位ビットが失われるためです。後でそれを 64 ビット ポインターにキャストすると、ポインターが正しくなくなり、それを使用しようとすると、メモリがクラッシュするか、暗黙のうちにメモリが破損します。

ここでの警告は、これらの潜在的な問題を回避するためのものです。この場合のように、ポインターの値が実際には実際のポインターではない場合、値が 0xffffffff を超えないことがわかっている場合は、整数にキャストしても完全に安全です。

警告を抑制する方法はいくつかあります。コンパイラのコマンド ラインでグローバルに無効にすることができます (推奨されません)。#pragmaコードの周りに a を使用して、警告を一時的に無効にすることができます (移植性はありません) 。または、巧妙なキャストを使用して回避することもできます。

と の 2 つのデータ型がintptr_tありuintptr_t、通常の整数と同じように動作します。他の整数型にアップキャスト/ダウンキャストしたり、あらゆる種類の算術演算を実行したりできますポインター値。32 ビット システムでintptr_tは、(少なくとも) 32 ビット幅になります。64 ビット システムでintptr_tは、(少なくとも) 64 ビット幅になります。2 つのタイプの唯一の違いは、署名されているのintptr_tに対しuintptr_t、署名されていないことです。

コンパイラは、これらの型が常にポインター値を保持するのに十分な大きさであることを認識しているため、ポインターをキャストしたりキャストしたりするときに警告を表示しません。整数ドメインに入ると、int警告を恐れずに通常のドメインにキャストできます。したがって、このコードは警告を排除する必要があります。

#include <stdint.h>
...
printf("thread 1 return code:%d\n", (int)(intptr_t)tret);  // line 44
printf("thread 2 return code:%d\n", (int)(intptr_t)tret);  // line 51
于 2014-01-28T05:07:38.950 に答える
-1

これを試してみてください。うまくいくはずです

thread_join の定義として、void **ではなく void ポインターが必要です。

err = pthread_join(tid1, (Void **)&tret);

値を返した後にそれを参照するため

printf("thread 1 return code:%d\n", *(int *)tret);
于 2014-01-28T05:19:05.770 に答える
-1
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void * thread_func1(void *args)
{
    printf("thread 1 returning\n");
    return ((void *)1);
}

void * thread_func2(void *args)
{
    printf("thread 2 exiting\n");
    pthread_exit((void *)2);
}

int main(void)
{
    int err;
    pthread_t tid1, tid2;
    int *tret = malloc(sizeof(int)); 

    err = pthread_create(&tid1, NULL, &thread_func1, NULL);
    if(err)
    {
        printf("cannot create thread 1\n");
    }
    err = pthread_create(&tid2, NULL, &thread_func2, NULL);
    if(err)
    {
        printf("cannot create thread 2\n");
    }

    err = pthread_join(tid1, (void *)tret);
    if(err)
    {
        printf("thread 1 join error\n");
    }
    printf("thread 1 return code:%d\n", *(tret));

    err = pthread_join(tid2, (void *)tret);
    if(err)
    {
        printf("cannot join thread 2\n");
    }
    printf("thread 2 return code:%d\n", *(tret));
    exit(0);
}

初めて警告を削除しただけで、コードを実行しませんでした...

これはあなたのすべてのコードです..警告なしで実行します:)

于 2014-01-28T04:47:21.537 に答える