gcc - Advertencia: emitir desde/hacia puntero desde/a entero de diferente tamaño
int void-pointers (4)
Estoy aprendiendo Pthreads. Mi código se ejecuta de la manera que quiero, puedo usarlo. Pero me da una advertencia sobre la compilación.
Yo compilo usando:
gcc test.c -o test -pthread
con GCC 4.8.1. Y me sale la advertencia
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;
^
Este error viene para el siguiente código:
#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);
}
¿Cómo puedo solucionar esta advertencia?
pthread_create(&(tid[i]), &attr, runner, (void *) i);
Está pasando la variable local i
como un argumento para el runner
, sizeof(void*) == 8
y sizeof(int) == 4
(64 bits).
Si quieres pasar i
, debes envolverlo como un puntero o algo así:
void *runner(void * param) {
int id = *((int*)param);
delete param;
}
int tid = new int; *tid = i;
pthread_create(&(tid[i]), &attr, runner, tid);
Es posible que solo desee i
, y en ese caso, lo siguiente debería ser seguro (pero lejos de ser recomendado):
void *runner(void * param) {
int id = (int)param;
}
pthread_create(&(tid[i]), &attr, runner, (void*)(unsigned long long)(i));
Intenta pasar
pthread_create(&(tid[i]), &attr, runner, (void*)&i);
También estaba recibiendo la misma advertencia. Así que para resolver mi advertencia, convertí int en mucho tiempo y luego esta advertencia simplemente desapareció. Y sobre la advertencia "convertir a puntero desde un entero de diferente tamaño" puede dejar esta advertencia porque un puntero puede contener el valor de cualquier variable porque el puntero en 64x es de 64 bits y en 32x es de 32 bits.
Una solución hacky rápida podría ser long
lugar de int
. En muchos sistemas, sizeof(long) == sizeof(void *)
.
Una mejor idea podría ser utilizar intptr_t
.
int threadnumber = (intptr_t) param;
y
pthread_create(&(tid[i]), &attr, runner, (void *)(intptr_t)i);