简体   繁体   中英

print value of void pointer

This is the fig11.3 in book Advanced programming in the UNIX Environment

#include <pthread.h>

#include "apue.h"

void* thr_fn1(void* arg) {
    printf("thread 1 returning\n");
    return ((void*)1);
}

void* thr_fn2(void* arg) {
    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, thr_fn1, NULL);
    if (err != 0) err_exit(err, "can't create thread 1");
    err = pthread_create(&tid2, NULL, thr_fn2, NULL);
    if (err != 0) err_exit(err, "can't create thread 2");

    err = pthread_join(tid1, &tret);
    if (err != 0) err_exit(err, "can't join with thread 1");
    printf("thread 1 exit code %ld\n", (long)tret);

    err = pthread_join(tid2, &tret);
    if (err != 0) err_exit(err, "can't join with thread 2");
    printf("thread 2 exit code %ld\n", (long)tret);
    exit(0);
}

I was confused that why I cannot typecast void pointer to pointer to long and dereference it

printf("thread 1 exit code %ld\n", *(long *)tret);

why can we typecast tret to long and get the correct value we want here

printf("thread 1 exit code %ld\n", (long)tret);

what's the type of tret here?

I show the easy case from GeeksforGeeks to print the value of void pointer below

#include<stdio.h> 
int main() 
{ 
    int a = 10; 
    void *ptr = &a; 
    printf("%d", *(int *)ptr); 
    return 0; 
} 

What's difference between two code above?

I think that's because according to the manual of pthread_join, it stores the return value of the thread, not a memory address: as you can see on the thr_fn1 and 2 functions, the return value is (void *)1 and (void *)2.

Dereferencing the pointer is pointless, as we are interested in his value, not the address he points to.

The second case uses this technique because ptr is actually a memory address.

I was confused that why I cannot typecast void pointer to pointer to long and dereference it

printf("thread 1 exit code %ld\n", *(long *)tret);

if you do that you dereference the address, but that address is 1 or 2 whose are very probably an invalid address, and even there are not you cannot make supposition of what they contain.

why can we typecast tret to long and get the correct value we want here

printf("thread 1 exit code %ld\n", (long)tret);

what's the type of tret here?

tret is a void * , and your thr_f<n> return a void * too, so the right way to do is:

printf("thread 1 exit code %p\n", tret);

else you suppose long and void* have the same size

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM