2016-04-10 25 views
1

問題を起こすことなく、voidへのvoid型ポインタをlong型に直接カスケードすることは可能ですか?以下は、コードhere(例:Pthread Joiningのページのセクション)から抜粋した少しのコードスニペットです。 this manual pageとして型キャストvoid * to long

{ 
    void *status; 
    long t; 
    rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); 
    rc = pthread_join(thread[t], &status); 
    printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status); 
} 

はpthread_joinを()はコピー対象スレッドの終了ステータス(すなわち、ターゲットスレッドがpthread_exit()に供給された値)の場所には、この中に* RETVAL(*状況によって指さと言います場合)。しかし、私が問題に言及したプログラムでは、地位はどこにも指さない。それでは、プログラムはまだどのように機能していますか?

第2に、私の知る限り、状態が長い値を保持することはできません。次に、型キャスト状態は、どのように長く、アドレスではない値を与えますか?

+1

重複:Busywork()関数内でバック実際の値を取得する:// stackoverflowの

rc = pthread_create(&thread[t], &attr, BusyWork, (void *)&t); 

を次に '問題' は

注意消える:

を使用して提案します.com/questions/12949383/conversion-primitive-data-type-to-void-pointer-type? –

+0

@MartinR:[this](http://man7.org/linux/man-pages/man3/pthread_join.3.html)によると、** pthread_join()はターゲットスレッドの終了ステータスをコピーします(つまり、 targetスレッドがpthread_exit(3)に供給した値)を* retval **が指し示す位置にコピーします。しかし、私が問題に言及したプログラムでは、_status_はどこにも指していないのですが、そのプログラムはどのように動作しますか? –

+0

これは偶然に動作します。変数ステータスは初期化されていないので、いつものステータスポイントに書き込みます。偶然、それはどこか合法的かもしれません。それがどこか違法であれば、クラッシュするでしょう。 – cup

答えて

1

クイック答え:長いが無効に収まるように保証されていません*:いいえ、

長い答えintptr_tを使用します。いくつかのシステム(特に64ビットIntel Linuxマシン)では、void *とlongが両方とも64ビットであり、インテル・プロセッサーは他のタイプの違いがないので動作します。 32ビットのIntel Linuxのような他のマシンでは、それらのマシンでは64ビットとvoid * 32ビットが長いので動作しません。よりエキゾチックな機械は、異なる特性を有する。

int < - >ポインタ変換をサポートする標準タイプは、stdint.hにあるintptr_tです。 POSIXプログラマーズ・マニュアルによると:

次の型はvoidへの任意の有効なポインタはvoidへのポインタに変換、その後、この型に変換することができますプロパティを持つ符号付き整数型を指定し、結果は、元のポインタに等しく比較する:

intptr_tだからintptr_tからの変換をサポートし、*無効にすることが保証されている不特定長さの符号付き整数型です。また、符号なしuintptr_tもあります。

Here is the definition of intptr_t in glibc。ご覧のとおり、64ビットマシンでは、intptr_tとlongは実際に同じタイプです。

+0

そのドキュメントは、 'intptr_t'は、ポインタの値を保持できると言っています。その逆もありません。例えば、ポインタが32ビットで、 'intptr_t'が64ビットの場合、それは要件を満たすでしょう。 (すなわち、ポインタから整数へのキャストと後ろへのキャストが機能します。)逆のプロパティを持つことが保証されている型はないと思います。 – Nemo

+0

これは良い点ですが、glibcソースを読むと、私は実際にその特定の実装で動作すると確信しています。しかし、私はそれが標準によって要求されていないことに同意します。明確にするために私の答えを編集してください。 – jforberg

0

このライン:

rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); 

が正しくありません。 HTTPの

long myVar = *parmVoidPtr; 
関連する問題