Как отличить целое число от указателя void?

Во время работы с Threads в C я сталкиваюсь с предупреждением

msgstr “предупреждение: приведение к указателю из целого разного размера”

Код выглядит следующим образом

#include #include #include #include void *print(void *id) { int a=10; printf("My thread id is %ld\n",pthread_self()); printf("Thread %d is executing\n",id); return (void *) 42; } int main() { pthread_t th[5]; int t; int i; int status; void *ret; for(i=0;i%d\n",(int *)ret); } pthread_exit(NULL); } 

Может ли кто-нибудь объяснить, как передать целое число функции, которая получает (void *) в качестве параметра?

Это прекрасный способ передать целые числа в новые pthreads, если это то, что вам нужно. Вам просто нужно подавить предупреждение, и это сделает это:

 #include  void *threadfunc(void *param) { int id = (intptr_t) param; ... } int i, r; r = pthread_create(&thread, NULL, threadfunc, (void *) (intptr_t) i); 

обсуждение

Это может оскорбить вашу чувствительность, но она очень короткая и не имеет условий гонки (как это было бы, если бы вы использовали &i ). Нет смысла писать несколько десятков строк дополнительного кода, чтобы получить кучу нумерованных streamов.

Гонки данных

Вот плохая версия с расчетом данных:

 #include  #include  #define N 10 void *thread_func(void *arg) { int *ptr = arg; // Has *ptr changed by the time we get here? Maybe! printf("Arg = %d\n", *ptr); return NULL; } int main() { int i; pthread_t threads[N]; for (i = 0; i < N; i++) { // NO NO NO NO this is bad! pthread_create(&threads[i], NULL, thread_func, &i); } for (i = 0; i < N; i++) { pthread_join(threads[i], NULL); } return 0; } 

Теперь, что происходит, когда я запускаю его с помощью дезинфицирующего средства для streamа?

(Кроме того, проверьте, как он печатает «5» дважды ...)

 ==================
 ПРЕДУПРЕЖДЕНИЕ: ThreadSanitizer: гонка данных (pid = 20494)
   Считайте размер 4 на 0x7ffc95a834ec по streamу T1:
     # 0 thread_func /home/depp/test.c:9 (a.out + 0x000000000a8c)
     # 1   (libtsan.so.0 + 0x000000023519)

   Предыдущая запись размером 4 на 0x7ffc95a834ec по основной теме:
     # 0 главная /home/depp/test.c:17 (a.out + 0x000000000b3a)

   Расположение - стопка основного streamа.

   Thread T1 (tid = 20496, работает), созданный по основному streamу:
     # 0 pthread_create  (libtsan.so.0 + 0x0000000273d4)
     # 1 главная /home/depp/test.c:18 (a.out + 0x000000000b1c)

 РЕЗЮМЕ: ThreadSanitizer: рассылка данных /home/depp/test.c:9 thread_func
 ==================
 Arg = 1
 Arg = 2
 Arg = 3
 Arg = 4
 Arg = 5
 Arg = 6
 Arg = 7
 Arg = 8
 Arg = 9
 Arg = 5
 ThreadSanitizer: сообщило 1 предупреждение

вы можете сделать что-то вроде этого:

 #include  #include  #include  #include  struct th { pthread_t thread; int id; int ret; }; void *print(void *id) { int a=10; struct th *self = (struct th *) id; printf("My thread id is %ld\n",pthread_self()); printf("Thread %d is executing\n",self->id); self->ret = random(); return; } int main(void) { struct th th[5]; int t; int i; int status; void *ret; for(i=0;i<5;i++) { th[i].id = i; status=pthread_create(&th[i].thread,NULL,print,&th[i]); //Getting warning at this line if(status) { printf("Error creating threads\n"); exit(0); } } for (i=0;i<5;i++) { pthread_join(th[i].thread,&ret); printf("%d--->%d\n",th[i].id,th[i].ret); } pthread_exit(NULL); } 

выведет:

 My thread id is 4496162816 My thread id is 4497870848 My thread id is 4498944000 My thread id is 4498407424 Thread 0 is executing Thread 1 is executing My thread id is 4499480576 Thread 3 is executing Thread 2 is executing 0--->1804289383 Thread 4 is executing 1--->846930886 2--->1714636915 3--->1681692777 4--->1957747793 

передача уникального указателя на каждый stream не будет гонка, и вы можете получить / сохранить любую информацию в th-й структуре

вы можете передать значение int как void pointer like (void *)&n где n – целое число, а в функции принимает указатель void как параметр, например void foo(void *n); и, наконец, внутри функции convert void указатель на int like, int num = *(int *)n; , таким образом вы не получите никаких предупреждений.

изменение:

 status=pthread_create(&th[i],NULL,print,(void *)i); 

чтобы:

 status=pthread_create(&th[i],NULL,print,(reinterpret_cast(i)); 

Reinterpret_cast делает int размером указателя, и предупреждение останавливается. В основном это лучшая версия (void *) i.

Interesting Posts

Как вы можете прочитать CSV-файл в R с различным количеством столбцов

Как восстановить поврежденный файл Excel

Что такое ru.v9.com и как его удалить?

Как напечатать f uint64_t? Сбой: «ложный трейлинг«% »в формате«

@Inject для передачи параметров в CDI @Named bean через URL

Подключение к Интернету слишком медленно

Почему Java не предлагает перегрузку оператора?

Как интерфейсы заменяют необходимость множественного наследования при наличии существующих classов

Все начальные пункты меню исчезли

Математические операции в регулярном выражении

Округление двойника, чтобы превратить его в int (java)

VLOOKUP с несколькими критериями, возвращающими значения в одной ячейке

Использование контекста приложения во всем мире?

Проверьте, была ли запущена текущая командная строка в качестве администратора

В чем разница между $ {var}, “$ var” и “$ {var}” в оболочке Bash?

Давайте будем гением компьютера.