URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8596
[ Назад ]

Исходное сообщение
"аргумент типа int для pthread_create в x86_64"

Отправлено Аноним , 24-Янв-10 22:39 
Код на С, портирую с x86 на x86_64 многопоточный сервер (точнее, превращаю его в многоплатформенный, чтобы работало и там и там, т.е. например unsigned int => uint32_t и другие вещи), так вот, после accept-a нужно передать сокет (тип int) в поток, делается это последним параметром фунции pthread_create, вот код:

...
socklen_t addr_len;
addr_len = sizeof(fsin);
accepted_socket = accept(s, (struct sockaddr *)&fsin, &addr_len);
....
....
pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)accepted_socket)

вот как объявлена функция pthread_create:

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg);


И так, так-как в x86_64 тип указатель (void*) это 64-битное число, а int - 32-битное, GCC выдает warning:

pthread_create warning: cast to pointer from integer of different size

Программа работает, и ошибок и быть не может, потому что ничего не вырезается, а наоборот, но вот как лучше всего сделть чтобы этого warning-a не было (это условие заказчика :)) Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.


Содержание

Сообщения в этом обсуждении
"аргумент типа int для pthread_create в x86_64"
Отправлено Michelnok , 24-Янв-10 23:57 
#include <stdint.h>
...
pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)(intptr_t)accepted_socket)

"аргумент типа int для pthread_create в x86_64"
Отправлено Аноним , 25-Янв-10 00:20 
>#include <stdint.h>
>...
>pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)(intptr_t)accepted_socket)

Спасибо! А можежь объяснить почему нужно два раза делать cast? Почему явное  преобразование из int в void* генерирует warning?


"аргумент типа int для pthread_create в x86_64"
Отправлено Michelnok , 25-Янв-10 00:49 
> Почему явное преобразование из int в void* генерирует warning?

Не знаю, покопайтесь на сайте GNU.
Предполагаю, что есть опасение перед преобразованием потенциально отрицательного 32-битного числа к беззнаковому 64-битному. Кстати, тогда наверное корректнее приводить к uintptr_t, а не к intptr_t. И сначала int в unsigned. Тогда точно враг не пройдет :)


"аргумент типа int для pthread_create в x86_64"
Отправлено const86 , 26-Янв-10 15:18 
>Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.

По такой логике, Ъ был предыдущий автор, за которым вы сейчас исправляете. Заведите структуру (с одним полем int) и передавайте в поток указатель на неё. Метод работает всегда одинаково и не нужно изобретать каждый раз новые хаки.


"аргумент типа int для pthread_create в x86_64"
Отправлено Аноним , 26-Янв-10 20:24 
>>Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.
>
>По такой логике, Ъ был предыдущий автор, за которым вы сейчас исправляете.
>Заведите структуру (с одним полем int) и передавайте в поток указатель
>на неё. Метод работает всегда одинаково и не нужно изобретать каждый
>раз новые хаки.

Тогда пришлось бы для каждой структуры делать malloc, потом free (иначе, будет небезопасно передавать всем потокам указатель на одну и ту же переменную (хоть локальную хоть глобальную), так как поток может и не успеть прочитать ее перед тем как она изменится для следующего потока в цикле). А делать malloc и free в программе, в которой до этого динамически выделяемая память не использовалась, я не стал, ведь нужно передать только один парметр.

P.S.
Я не очень опытный кодер на С, так что может что-то и недопонимаю ;)


"аргумент типа int для pthread_create в x86_64"
Отправлено const86 , 27-Янв-10 01:03 
>Тогда пришлось бы для каждой структуры делать malloc, потом free

Если количество потоков фиксировано или ограничено небольшим числом, то можно завести статичный массив под параметры. Иначе да, придётся делать malloc/free.

Кстати, что гласит стандарт на тему sizeof(int) <= sizeof(void *)?


"аргумент типа int для pthread_create в x86_64"
Отправлено Michelnok , 28-Янв-10 17:49 
>Кстати, что гласит стандарт на тему sizeof(int) <= sizeof(void *)?

AFAIK, ничего.