0

I recently read a book about how to write code in unix environment.There is an expample code making me very confused.

The example code:

#include "apue.h"
#include <pthread.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);
}

How to figure out "(void *)1" or "(void *)2" ? Is okey to turn type "void *" to type "long" ? In my opinion, "(void *)1" tells me 1 is an address, but when I use deref to get the value stored at address 1, it's obviously wrong. So, I think this code is crazy.

JasonZhang
  • 68
  • 1
  • 10
  • 1
    Thread functions must return a pointer. By using e.g. `(void *) 1` the code is trying to return an actual value rather than a pointer. To be more correct, it should really be `(void *) (intptr_t) 1`. And the opposite conversion should be done when reading the value: `(int) (intptr_t) tret`. – Some programmer dude Sep 25 '22 at 12:38
  • @Someprogrammerdude Please write an actual answer, not a comment. This is not a forum. – the busybee Sep 25 '22 at 13:18

1 Answers1

1

what's the meaning of "(void *)2" in c code?

It means convert the value two to the type “pointer to void”.

pthread_exit((void *)2);

Normally a thread should return a pointer to data (either with the normal function return mechanism or by passing it as an argument to pthread_exit). In this case, the data is so small, the author decided it is not worth allocating memory just for the data; they will simply use the pointer itself to represent the data. So they cast the desired value to the void * type.

The behavior of this is not fully defined by the C standard, but it works in many C implementations, particularly those for Unix systems. The caller should convert the void * back to an integer type to interpret the value.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312