警告:不同大小的整数与指针之间进行转换

35

我正在学习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);
}

我该怎么修复这个警告?


在我的机器上,我不得不将它转换为 uint64_t 才能消除警告。 - undefined
4个回答

64

一个快速而不够严谨的解决方法可能是将类型转换为long而不是int。在许多系统上,sizeof(long) == sizeof(void *)

更好的方法可能是使用intptr_t

int threadnumber = (intptr_t) param;

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

1
在64位计算机/编译器上,或将其强制转换为long long - thejinx0r
@thejinx0r 当然可以,但从某种意义上来说,这仍然是一种hack,因为您不能依赖于 sizeof(long long) == sizeof(void *) - tangrs
1
@NikhilWagh,你不能总是依赖于 sizeof(size_t) == sizeof(void *) - tangrs
在64位机器上,没有任何方法有效。我不得不先声明一个long类型的变量,然后将其作为参数传递给线程函数。 long i; pthread_create(&pid[i], NULL, displayThread, (void *)i); - Fahad Naeem

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

您正在将本地变量i作为runner的参数传递,sizeof(void*) == 8sizeof(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));

1
我也遇到了同样的警告。所以为了解决这个警告,我将int转换为long,然后这个警告就消失了。至于“从不同大小的整数转换为指针”的警告,您可以忽略它,因为指针可以保存任何变量的值,因为64x中的指针是64位的,在32x中是32位的。

-4
尝试传递。
pthread_create(&(tid[i]), &attr, runner, (void*)&i);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接