Предупреждение: приведение к/от указателя из/в целое число разного размера

Я изучаю Pthreads. Мой код выполняется так, как я хочу, я могу его использовать. Но это дает мне предупреждение при компиляции.

Я компилирую, используя:

gcc test.c -o test -pthread

с GCC 4.8.1. И я получаю предупреждение

test.c: In function ‘main’:
test.c:39:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     pthread_create(&(tid[i]), &attr, runner, (void *) i);
                                              ^
test.c: In function ‘runner’:
test.c:54:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   int threadnumber = (int) param;
                      ^

Эта ошибка возникает для следующего кода:

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

#define MAX_THREADS 10

int sum; /* this data is shared by the thread(s) */
void *runner(void * param);

int main(int argc, char *argv[])
{
  int num_threads, i;
  pthread_t tid[MAX_THREADS];     /* the thread identifiers  */
  pthread_attr_t attr; /* set of thread attributes */

  if (argc != 2) {
    fprintf(stderr, "usage:  test <integer value>\n");
    exit(EXIT_FAILURE);
  }

  if (atoi(argv[1]) <= 0) {
    fprintf(stderr,"%d must be > 0\n", atoi(argv[1]));
    exit(EXIT_FAILURE);
  }

  if (atoi(argv[1]) > MAX_THREADS) {
    fprintf(stderr,"%d must be <= %d\n", atoi(argv[1]), MAX_THREADS);
    exit(EXIT_FAILURE);
  }

  num_threads = atoi(argv[1]);
  printf("The number of threads is %d\n", num_threads);

  /* get the default attributes */
  pthread_attr_init(&attr);

  /* create the threads */
  for (i=0; i<num_threads; i++) {
    pthread_create(&(tid[i]), &attr, runner, (void *) i);
    printf("Creating thread number %d, tid=%lu \n", i, tid[i]);
  }

  /* now wait for the threads to exit */
  for (i=0; i<num_threads; i++) {
    pthread_join(tid[i],NULL);
  }
  return 0;
}

/* The thread will begin control in this function */
void *runner(void * param)
{
  int i;
  int threadnumber = (int) param;
  for (i=0; i<1000; i++) printf("Thread number=%d, i=%d\n", threadnumber, i);
  pthread_exit(0);
}

Как я могу исправить это предупреждение?


person user159    schedule 24.01.2014    source источник


Ответы (4)


Быстрое хакерское исправление может просто привести к long вместо int. Во многих системах sizeof(long) == sizeof(void *).

Лучшей идеей может быть использование intptr_t.

int threadnumber = (intptr_t) param;

а также

pthread_create(&(tid[i]), &attr, runner, (void *)(intptr_t)i);
person tangrs    schedule 24.01.2014
comment
или привести к long long на 64-битных машинах/компиляторах. - person thejinx0r; 11.09.2017
comment
@ thejinx0r Конечно, но это все еще хак в том смысле, что вы не можете полагаться на sizeof(long long) == sizeof(void *). - person tangrs; 11.09.2017
comment
@NikhilWagh еще раз, вы не всегда можете полагаться на sizeof(size_t) == sizeof(void *). - person tangrs; 23.10.2017
comment
У меня ничего не работало на 64-битной машине. Мне пришлось объявить переменную длинного типа перед передачей в качестве аргумента функции потока. long i; pthread_create(&pid[i], NULL, displayThread, (void *)i); - person Fahad Naeem; 01.11.2019

pthread_create(&(tid[i]), &attr, runner, (void *) i);

Вы передаете локальную переменную i в качестве аргумента для runner, sizeof(void*) == 8 и sizeof(int) == 4 (64 бита).

Если вы хотите передать i, вы должны обернуть его как указатель или что-то в этом роде:

void *runner(void * param) {
  int id = *((int*)param);
  delete param;
}

int tid = new int; *tid = i;
pthread_create(&(tid[i]), &attr, runner, tid);

Вы можете просто захотеть i, и в этом случае следующее должно быть безопасным (но далеко не рекомендуемым):

void *runner(void * param) {
  int id = (int)param;
}

pthread_create(&(tid[i]), &attr, runner, (void*)(unsigned long long)(i));
person JuanR    schedule 24.01.2014

Я также получил такое же предупреждение. Итак, чтобы разрешить мое предупреждение, я преобразовал его в длинное, а затем это предупреждение просто исчезло. А по поводу предупреждения "приведение к указателю из целого числа разного размера" вы можете оставить это предупреждение, потому что указатель может содержать значение любой переменной, потому что указатель в 64x имеет 64 бита, а в 32x - 32 бита.

person newbie    schedule 17.09.2015

Попробуйте пройти

pthread_create(&(tid[i]), &attr, runner, (void*)&i);
person venkatesh    schedule 14.03.2018