Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Typecasting Pointers on a 64 bit System

Reply
Thread Tools

Typecasting Pointers on a 64 bit System

 
 
Quentin Pope
Guest
Posts: n/a
 
      11-10-2011
What is the best way to handle this warning:

warning: cast from pointer to integer of different size

I am casting in and out of a function that requires a pointer type. I
am casting an integer as a pointer, but the pointer is 8 bytes while
the integer is only 4 bytes.

Here's an example function:

pthread_create(&tid, NULL, readit, (void *)(long)connfd)

I need to pass the file descriptor as a void * for pthread_create. But
I need the file descriptor as an integer to read and write to it. Is the
above the best approach to turn off the warning? I am considering just
typecasting to size_t before typecasting to the pointer. Is that a
better approach than typecasting to long since size_t should remain equal
to the size of pointers?

Of course, I run into the reverse problem when I have to close the
file descriptor.

close((int) arg);

I don't even know what to do in the above case. I shouldn't be
truncating anything, so I should be okay.

I originally wrote the code using a 32 bit version, so I am receiving
these errors when I ported it over to a 64 bit version.
 
Reply With Quote
 
 
 
 
Lauri Alanko
Guest
Posts: n/a
 
      11-10-2011
In article <j9hbnp$13g$(E-Mail Removed)>,
Quentin Pope <(E-Mail Removed)> wrote:
> pthread_create(&tid, NULL, readit, (void *)(long)connfd)
>
> I need to pass the file descriptor as a void * for pthread_create. But
> I need the file descriptor as an integer to read and write to it. Is the
> above the best approach to turn off the warning?


No.

Just pass a pointer to the fd:

pthread_create(&tid, NULL, readit, &connfd);

Then dereference the pointer in the readit function to get the
descriptor. If connfd is a local variable, you need to make sure that
connfd doesn't exit the scope before the new thread has read it. If
this is difficult, you can allocate a new copy for the thread:

int* fdp = malloc(sizeof(int));
*fdp = connfd;
pthread_create(&tid, NULL, readit, fdp);

void readit(void* fdp) {
int connfd = *(int*)fdp;
free(fdp);
...;
}


Lauri
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      11-10-2011
Quentin Pope <(E-Mail Removed)> writes:

> What is the best way to handle this warning:
>
> warning: cast from pointer to integer of different size


The best way may be to avoid casting between a pointer and an
integer.

Another way is to use (u)intptr_t from <stdint.h>, which is
ordinarily defined as an integer type that is the same width as a
pointer.
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      11-10-2011
On 11/10/2011 03:32 PM, Ben Pfaff wrote:
....
> Another way is to use (u)intptr_t from <stdint.h>, which is
> ordinarily defined as an integer type that is the same width as a
> pointer.


More accurately, it's defined to be big enough for the conversion to be
reversible. In practice, it's likely to be the same size, but that's not
part of the definition. It could easily be larger. If there's any
redundancy in the pointer representation, and the conversion removes
that redundancy, it could even be smaller.
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      11-10-2011
On 2011-11-10, Quentin Pope <(E-Mail Removed)> wrote:
> What is the best way to handle this warning:
>
> warning: cast from pointer to integer of different size


Use an integer of a suitable size.

> I am casting in and out of a function that requires a pointer type. I
> am casting an integer as a pointer, but the pointer is 8 bytes while
> the integer is only 4 bytes.


In the C99 language, there is the intptr_t type for this sort of thing.

For older dialects of C, you have to cob together some kind of compile
time configuration. Define the type as a typedef and change it based
on target compiler and platform.

I've written a configure script which detects what integral type is
suitable for holding pointers (based on size) and throws the info
into a "config.h" header.

This is BSD licensed so you can borrow it.

http://www.kylheku.com/cgit/txr/tree/configure

The approach taken in this script is to compile a sample translation unit and
then inspect the symbols (using the POSIX-standard nm command).

This creates an int_ptr_t typedef in "config.h" along with macros
giving the minimum and maximum value.

It's only been tested on various GNU/Linux architectures, Cygwin and MinGW.

It supports cross-compiling because the test programs are only compiled, never
executed.
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      11-10-2011
On 2011-11-10, Lauri Alanko <(E-Mail Removed)> wrote:
> In article <j9hbnp$13g$(E-Mail Removed)>,
> Quentin Pope <(E-Mail Removed)> wrote:
>> pthread_create(&tid, NULL, readit, (void *)(long)connfd)
>>
>> I need to pass the file descriptor as a void * for pthread_create. But
>> I need the file descriptor as an integer to read and write to it. Is the
>> above the best approach to turn off the warning?

>
> No.
>
> Just pass a pointer to the fd:
>
> pthread_create(&tid, NULL, readit, &connfd);


Ths is an inferior approach because now the object &connfd has
to remain stable for as long as the created thread wants to touch
that object.

> Then dereference the pointer in the readit function to get the
> descriptor. If connfd is a local variable, you need to make sure that
> connfd doesn't exit the scope before the new thread has read it.


You need to ensure that AND that the object is not overwritten with a different
value (e.g. in a loop that launches more than one thread).

In this case, why use threads? Just call "readit" directly from
this thread.

If the parent thread has to be confined while a thread executes, there is no
point. Just thread creation and context switching overhead.

What you can do is implement some little "mousetrap" protocol
wherby the thread indicates "I have consumed the argument, you can
trash it now". E.g condition variable, etc.

Or you could just cast the darn value to a pointer!

> this is difficult, you can allocate a new copy for the thread:
>
> int* fdp = malloc(sizeof(int));
> *fdp = connfd;
> pthread_create(&tid, NULL, readit, fdp);


Or just cast the darn value to a pointer. Save this trick for when the argument
list grows to include more than one value.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-10-2011
Ben Pfaff <(E-Mail Removed)> writes:
> Quentin Pope <(E-Mail Removed)> writes:
>> What is the best way to handle this warning:
>>
>> warning: cast from pointer to integer of different size

>
> The best way may be to avoid casting between a pointer and an
> integer.
>
> Another way is to use (u)intptr_t from <stdint.h>, which is
> ordinarily defined as an integer type that is the same width as a
> pointer.


But (u)intptr_t won't exist on systems where no integer type is
wide enough to hold a converted pointer value without loss of
information, so code that depends on it is non-portable. But if
you insist on passing an integer value in a pointer argument,
uintptr_t or intptr_t is the way to go.

In this case, the intent of the "arg" argument to pthread_create()
is that it should be a pointer to data needed by the start routine.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      11-10-2011
On 2011-11-10, Kaz Kylheku <(E-Mail Removed)> wrote:
> On 2011-11-10, Lauri Alanko <(E-Mail Removed)> wrote:
>> int* fdp = malloc(sizeof(int));
>> *fdp = connfd;
>> pthread_create(&tid, NULL, readit, fdp);

>
> Or just cast the darn value to a pointer. Save this trick for when the argument
> list grows to include more than one value.


P.S. what is more important: having an allergic reaction to
pointer-integer casts? Or checking the return value of malloc.


 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      11-10-2011
On 2011-11-10, Kaz Kylheku <(E-Mail Removed)> wrote:
> On 2011-11-10, Quentin Pope <(E-Mail Removed)> wrote:
>> What is the best way to handle this warning:
>>
>> warning: cast from pointer to integer of different size

>
> Use an integer of a suitable size.
>
>> I am casting in and out of a function that requires a pointer type. I
>> am casting an integer as a pointer, but the pointer is 8 bytes while
>> the integer is only 4 bytes.

>
> In the C99 language, there is the intptr_t type for this sort of thing.
>
> For older dialects of C, you have to cob together some kind of compile
> time configuration. Define the type as a typedef and change it based
> on target compiler and platform.
>
> I've written a configure script which detects what integral type is
> suitable for holding pointers (based on size) and throws the info
> into a "config.h" header.


But, by the way, I would not bother with this for something so trivial.

Here, your pointer type is larger than the integer you are trying to
pass through, so it doesn't matter.

Just kill the warning for that source file.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      11-10-2011
On 11/10/2011 03:51 PM, Kaz Kylheku wrote:
> On 2011-11-10, Lauri Alanko <(E-Mail Removed)> wrote:
>> In article <j9hbnp$13g$(E-Mail Removed)>,
>> Quentin Pope <(E-Mail Removed)> wrote:
>>> pthread_create(&tid, NULL, readit, (void *)(long)connfd)
>>>
>>> I need to pass the file descriptor as a void * for pthread_create. But
>>> I need the file descriptor as an integer to read and write to it. Is the
>>> above the best approach to turn off the warning?

>>
>> No.
>>
>> Just pass a pointer to the fd:
>>
>> pthread_create(&tid, NULL, readit, &connfd);

>
> Ths is an inferior approach because now the object &connfd has
> to remain stable for as long as the created thread wants to touch
> that object.
>
>> Then dereference the pointer in the readit function to get the
>> descriptor. If connfd is a local variable, you need to make sure that
>> connfd doesn't exit the scope before the new thread has read it.

....
> Or you could just cast the darn value to a pointer!


Unless you're worried about the possibility that the result of the
conversion is a trap representation, as is explicitly allowed by the C
standard. Does POSIX say something to guarantee that this is not a
possibility?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Typecasting pointers Nishu C Programming 26 01-30-2007 02:33 PM
Typecasting Pointers on a 64 bit System bwaichu@yahoo.com C Programming 12 08-08-2006 09:44 PM
typecasting of function pointers srinivas.satish@gmail.com C Programming 12 03-21-2006 05:33 PM
Typecasting function pointers to void * bnoordhuis@gmail.com C Programming 3 07-15-2005 07:13 AM
Typecasting Pointers brian C Programming 13 11-29-2004 03:45 PM



Advertisments