2014-01-24 2 views
20

Я изучаю 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); 
} 

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

ответ

34

быстрая Hacky исправление может просто бросить в long вместо int. На большом количестве систем, sizeof(long) == sizeof(void *).

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

int threadnumber = (intptr_t) param; 

и

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

или наложить на 'long long' на 64-битных машинах/компиляторах. – thejinx0r

+0

@ thejinx0r Уверен, но это все еще взломать в том смысле, что вы не можете полагаться на 'sizeof (long long) == sizeof (void *)'. – tangrs

+0

или отдать его 'size_t', который сработал для меня. –

1
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)); 
0

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