J'apprends des Pthreads. Mon code s'exécute comme je le veux, je peux l'utiliser. Mais cela me donne un avertissement sur la compilation.
Je compile en utilisant:
gcc test.c -o test -pthread
avec GCC 4.8.1. Et je reçois l'avertissement
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;
^
Cette erreur vient pour le code suivant:
#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);
}
Comment puis-je résoudre cet avertissement?
Un correctif rapide de hacky pourrait simplement être utilisé pour long
au lieu de int
Sur beaucoup de systèmes, sizeof(long) == sizeof(void *)
.
Une meilleure idée pourrait être d'utiliser intptr_t
.
int threadnumber = (intptr_t) param;
et
pthread_create(&(tid[i]), &attr, runner, (void *)(intptr_t)i);
pthread_create(&(tid[i]), &attr, runner, (void *) i);
Vous transmettez la variable localei
en tant qu'argument pour runner
, sizeof(void*) == 8
et sizeof(int) == 4
(64 bits).
Si vous voulez passer i
, vous devriez l'envelopper comme un pointeur ou quelque chose comme ça:
void *runner(void * param) {
int id = *((int*)param);
delete param;
}
int tid = new int; *tid = i;
pthread_create(&(tid[i]), &attr, runner, tid);
Vous voudrez peut-être juste i
, et dans ce cas, les éléments suivants devraient être sûrs (mais loin d'être recommandés):
void *runner(void * param) {
int id = (int)param;
}
pthread_create(&(tid[i]), &attr, runner, (void*)(unsigned long long)(i));
Je recevais aussi le même avertissement. Donc, pour résoudre mon avertissement, j’ai converti int en long et cet avertissement a tout simplement disparu. Et à propos de l'avertissement "attribution d'un pointeur à partir d'un entier de taille différente", vous pouvez laisser cet avertissement, car un pointeur peut contenir la valeur de toute variable car le pointeur dans 64x est de 64 bits et dans 32x de 32 bits.