Код на С, портирую с 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 не было (это условие заказчика :)) Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.
#include <stdint.h>
...
pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)(intptr_t)accepted_socket)
>#include <stdint.h>
>...
>pthread_create(&th, &ta, (void * (*)(void *))parser, (void *)(intptr_t)accepted_socket)Спасибо! А можежь объяснить почему нужно два раза делать cast? Почему явное преобразование из int в void* генерирует warning?
> Почему явное преобразование из int в void* генерирует warning?Не знаю, покопайтесь на сайте GNU.
Предполагаю, что есть опасение перед преобразованием потенциально отрицательного 32-битного числа к беззнаковому 64-битному. Кстати, тогда наверное корректнее приводить к uintptr_t, а не к intptr_t. И сначала int в unsigned. Тогда точно враг не пройдет :)
>Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.По такой логике, Ъ был предыдущий автор, за которым вы сейчас исправляете. Заведите структуру (с одним полем int) и передавайте в поток указатель на неё. Метод работает всегда одинаково и не нужно изобретать каждый раз новые хаки.
>>Конечно, можно решить проблему используя еще одну переменную "прокси", но как-то не Ъ.
>
>По такой логике, Ъ был предыдущий автор, за которым вы сейчас исправляете.
>Заведите структуру (с одним полем int) и передавайте в поток указатель
>на неё. Метод работает всегда одинаково и не нужно изобретать каждый
>раз новые хаки.Тогда пришлось бы для каждой структуры делать malloc, потом free (иначе, будет небезопасно передавать всем потокам указатель на одну и ту же переменную (хоть локальную хоть глобальную), так как поток может и не успеть прочитать ее перед тем как она изменится для следующего потока в цикле). А делать malloc и free в программе, в которой до этого динамически выделяемая память не использовалась, я не стал, ведь нужно передать только один парметр.
P.S.
Я не очень опытный кодер на С, так что может что-то и недопонимаю ;)
>Тогда пришлось бы для каждой структуры делать malloc, потом freeЕсли количество потоков фиксировано или ограничено небольшим числом, то можно завести статичный массив под параметры. Иначе да, придётся делать malloc/free.
Кстати, что гласит стандарт на тему sizeof(int) <= sizeof(void *)?
>Кстати, что гласит стандарт на тему sizeof(int) <= sizeof(void *)?AFAIK, ничего.