warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
Asked Answered
C

3

5

part of my code:

int server_sockfd, client_sockfd; //socket file descriptors of client and server

// ... some code 

if(pthread_create(&vlakno, NULL, handle_client, (int *) client_sockfd) != 0) {
            perror("Error while creating thread.");
        }

I'm getting "warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]"

prototype of my function:

void *handle_client(void *args);

I found this question:
link

The first answer said something like that he should use intptr_t instead of int.
I have two questions:
What is difference between int and intptr_t in my case?
What should I do?

I have 2 ideas:
1st: (changing type of file descriptors)

 int server_sockfd, client_sockfd; //socket file descriptors of client and server

    // ... some code 

    if(pthread_create(&vlakno, NULL, handle_client, (intptr_t *) client_sockfd) != 0) {
                perror("Error while creating thread.");
            }

or 2nd idea: (changing type only in casting function pthread_create)

intptr_t server_sockfd, client_sockfd; //socket file descriptors of client and server

        // ... some code 

        if(pthread_create(&vlakno, NULL, handle_client, (int *) client_sockfd) != 0) {
                    perror("Error while creating thread.");
                }

EDIT:
in function handle_client i want to do this:

int clientSocket;
clientSocket = (int)args;

I'm really sorry to user cnicar or something like that .. he unfortunatelly deleted his answer but it was ok.
His solution was use (void *), it firstly casted same same error but it was caused probably bad behaviour of eclipse :( So message for him:
Ok thanks it looks thats fine now ... Eclipse still throwed this warning but when I turned it on and off twice afer edit it fine with your edit :) thanks a lot

Critchfield answered 12/2, 2012 at 17:49 Comment(2)
How about passing a pointer to the FD, as in &client_sockfd?Tigrinya
@KerrekSB please look at my edit if your suggestions is ok with that. ('m not sure when I'm using pointers)Critchfield
A
8

You have declared client_sockfd as an int. You shouldn't cast that to an int * that way.

Use the & operator, to get the address of client_sockfd, instead if you meant to give a pointer to client_sockfd:

pthread_create(&vlakno, NULL, handle_client, &client_sockfd)
                                          // ^ & operator

Do watch out for the lifetime of client_sockfd, it must outlive the thread to prevent race conditions (see the comments).


The difference between int and intptr_t is that int is meant to hold an integer, while intptr_t is meant to hold an address in form of an integer. intptr_t is guaranteed to be able to hold a pointer, while int is not.

If your intention was to pass the value of client_sockfd, cast it to an intptr_t:

pthread_create(&vlakno, NULL, handle_client, (intptr_t)client_sockfd)
Aec answered 12/2, 2012 at 17:52 Comment(4)
Passing &client_sockfd is not safe unless you add synchronization to ensure that the caller does not return before the new thread uses the pointed-to value! OP's original code was correct despite the warning, and a useless cast through uintptr_t would avoid the warning.Nitre
To be clear: OP's version only has a bug on obscure compilers where int-to-void *-to-int round trip is not safe. As far as I know, no such compiler exists - certainly none exist which also support POSIX threads. On the other hand, your version has a serious race condition bug on every system out there.Nitre
@R.. in the same time C doesn't guarantee that an integer value is preserved after the round trip if it is an int and not a uintptr_t or an intptr_t.Dryclean
@Aec I have a different situation and used your answer and the warning went away :) I function CreateWindowEx the 10th argument required typecast to HMENU but only typecasting didn't work so I used this (HMENU)&uWindowId and problem solved. Thanks man,Isoagglutination
S
4
(int *) client_sockfd

client_sockfd is not a pointer. It's an int, which is not the same size as an int *. And it's telling you that.

The last argument to pthread_create() is a void * and is meant to be a pointer to data that you want to pass into that particular thread. It appears you're trying to convert the integer value of client_sockfd to a pointer and pass that. That's generally not something you would do, but if you really want to and avoid the warning then you need to use something that is the same size as a pointer, which is what intptr_t gives you. More than likely int is 4 bytes and intptr_t (and void *) is eight bytes on your system, but that is platform dependent. While you can safely go from 32->64->32 bits, the compiler is warning you that you have different sizes.

Shangrila answered 12/2, 2012 at 17:51 Comment(2)
The last argument to pthread_create can also pass integer arguments as long as the value safely fits in void * via the implementation's conversion from int to void * to int.Nitre
Just because you can do something doesn't mean you should. That being said ... that's exactly what the last paragraph of my answer says. I'll add some clarity to explicitly talk about sizes.Shangrila
D
0

(int *) client_sockfd is not equivalent to &client_sockfd.

The first converts the value of client_sockfd to an int * and the second form yields a pointer to client_sockfd.

It is the latter expression you have to use for pthread_create last argument.

Dryclean answered 12/2, 2012 at 17:54 Comment(3)
Passing &client_sockfd is incorrect and extremely unsafe unless you add synchronization to ensure its lifetime does not end before the new thread uses it. OP's code is correct despite the warning. You can eliminate the warning with a useless cast through uintptr_t.Nitre
@R.. Depending on how handle_client is implemented passing a copy of client_sockfd converted to a pointer type can be just wrong. Regarding the lifetime of the object client_sockfd, nothing in the OP question tells us that it doesn't have static storage duration or that the descriptor could be accessed in a unsafe manner.Dryclean
I'm assuming it's not static because static storage duration for threads is just a formula for writing crap code. Actually the same would be true even without the phrase "for threads". I agree it's possible that the handle_client function is expecting a pointer, but I doubt it since OP asked the question about a warning and not about why handle_client is crashing...Nitre

© 2022 - 2024 — McMap. All rights reserved.