Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   casting unsigned int to void* (http://www.velocityreviews.com/forums/t948760-casting-unsigned-int-to-void.html)

Fred K 07-30-2012 05:33 PM

casting unsigned int to void*
 
The Xpm pixmap library contains code that casts an unsigned int
to a (void *), passing that as an argument to a function
that expects a (void *):

/* Function prototype: */
xpmHashIntern (xpmHashTable *table, char *tag, void *data));

/* Calling it, casting 3rd argument: */
int a = <something>;
xpmHashIntern(hashtable, color->string, (void *)a );

On a 64-bit platform where pointers are 64 bits and ints
are 32 bits, is this safe?

Eric Sosman 07-30-2012 05:59 PM

Re: casting unsigned int to void*
 
On 7/30/2012 1:33 PM, Fred K wrote:
> The Xpm pixmap library contains code that casts an unsigned int
> to a (void *), passing that as an argument to a function
> that expects a (void *):
>
> /* Function prototype: */
> xpmHashIntern (xpmHashTable *table, char *tag, void *data));
>
> /* Calling it, casting 3rd argument: */
> int a = <something>;
> xpmHashIntern(hashtable, color->string, (void *)a );
>
> On a 64-bit platform where pointers are 64 bits and ints
> are 32 bits, is this safe?


For suitable definitions of "safe," yes. Presumably the goal
is to be able to convert the `void*' back to an `unsigned(?) int'
and recover the original "<something>". If so,

- The C language does not guarantee that this will work (no,
not even if you use `intptr_t' or `uintptr_t'), but

- It will work on every 64-bit machine I've ever encountered,
and I haven't heard of any where it wouldn't.

--
Eric Sosman
esosman@ieee-dot-org.invalid

James Kuyper 07-30-2012 06:14 PM

Re: casting unsigned int to void*
 
On 07/30/2012 01:33 PM, Fred K wrote:
> The Xpm pixmap library contains code that casts an unsigned int
> to a (void *), passing that as an argument to a function
> that expects a (void *):
>
> /* Function prototype: */
> xpmHashIntern (xpmHashTable *table, char *tag, void *data));
>
> /* Calling it, casting 3rd argument: */
> int a = <something>;
> xpmHashIntern(hashtable, color->string, (void *)a );
>
> On a 64-bit platform where pointers are 64 bits and ints
> are 32 bits, is this safe?



The fact that pointers are 64 bits and ints are 32 bits makes it more
difficult for this to work, but not impossible. On a platform where both
are the same size, it's more likely to work, but that's still not
guaranteed. The precise requirements are as follows:

Converting an integer constant expression with a value of 0 to void* is
guaranteed by the standard to result in a null pointer value.

Converting a pointer to void into either intptr_t or uintptr_t produces
a value that can be converted back to void*, resulting in a pointer that
is equivalent to the original pointer. Those two types are optional; if
supported, they are defined in <stdint.h>, which was introduced in C99.
You can check whether they are supported by checking whether INTPTR_MAX
or UINTPTR_MAX are #defined.

In all other cases, while converting an integer value to a pointer is
permitted, "the result is implementation-defined, might not be correctly
aligned, might not point to an entity of the referenced type, and might
be a trap representation."

Whether or not this code works correctly is therefore
implementation-specific. It would never have been written and released
unless it actually did work, somewhere, but that's no guarantee that it
will work anywhere else.

Fred K 07-30-2012 06:23 PM

Re: casting unsigned int to void*
 
On Monday, July 30, 2012 11:14:34 AM UTC-7, James Kuyper wrote:
> On 07/30/2012 01:33 PM, Fred K wrote: > The Xpm pixmap library contains code that casts an unsigned int > to a (void *), passing that as an argumentto a function > that expects a (void *): > > /* Function prototype: */ > xpmHashIntern (xpmHashTable *table, char *tag, void *data)); > > /* Calling it, casting 3rd argument: */ > int a = <something>; > xpmHashIntern(hashtable, color->string, (void *)a ); > > On a 64-bit platform where pointers are 64 bits and ints > are 32 bits, is this safe? The fact that pointers are64 bits and ints are 32 bits makes it more difficult for this to work, butnot impossible. On a platform where both are the same size, it's more likely to work, but that's still not guaranteed. The precise requirements are as follows: Converting an integer constant expression with a value of 0 to void* is guaranteed by the standard to result in a null pointer value. Converting a pointer to void into either intptr_t or uintptr_t produces a value that can be converted back to void*, resulting in a pointer that is equivalent to the original pointer. Those two types are optional; if supported, they are defined in <stdint.h>, which was introduced in C99. You can check whether they are supported by checking whether INTPTR_MAX or UINTPTR_MAX are #defined. In all other cases, while converting an integer value to a pointer is permitted, "the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation." Whether or not this code works correctly is therefore implementation-specific. It would never have been written and released unless it actually did work, somewhere, but that's no guarantee that it will work anywhere else.


Well, it was written a long time ago, and for platforms where the size of an int was the same size as a pointer. So far, I haven't found a problem with it on an HP-UX, SGI, Sun, AIX; I'm now porting it to several flavors of (64-bit) Linux, and iPad. Time will tell...

Alan Curry 07-30-2012 06:46 PM

Re: casting unsigned int to void*
 
There was some really unforgivable formatting in here, especially the more
deeply quoted parts, so I chopped them out. Google Groups sucks! Get a
real newsreader!

In article <afc78550-acc3-4f3f-b9e6-5dcbe1e33061@googlegroups.com>,
Fred K <fred.l.kleinschmidt@gmail.com> wrote:
[about xpm]
>
>Well, it was written a long time ago, and for platforms where the size
>of an int was the same size as a pointer. So far, I haven't found a
>problem with it on an HP-UX, SGI, Sun, AIX; I'm now porting it to
>several flavors of (64-bit) Linux, and iPad. Time will tell...


Xpm isn't some dead artifact you just dug up that nobody else remembers. It has
been continuously maintained and is still distributed by x.org.

Why can't you use their version? It should already be bundled with your
Linux distribution.

--
Alan Curry

Edward A. Falk 07-30-2012 07:03 PM

Re: casting unsigned int to void*
 
In article <jv6i1p$ch0$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
>On 7/30/2012 1:33 PM, Fred K wrote:
>
> For suitable definitions of "safe," yes. Presumably the goal
>is to be able to convert the `void*' back to an `unsigned(?) int'
>and recover the original "<something>". If so,
>
> - The C language does not guarantee that this will work (no,
> not even if you use `intptr_t' or `uintptr_t'), but
>
> - It will work on every 64-bit machine I've ever encountered,
> and I haven't heard of any where it wouldn't.


Agreed. The spec may not support it, but it should be safe on
most machines, as long as the size of void* is >= the size of int.

It would fail on a 286 with the wrong compiler options, and maybe a
PDP-11, but would be safe on any other machine I've ever worked on.

--
-Ed Falk, falk@despams.r.us.com
http://thespamdiaries.blogspot.com/

Fred K 07-30-2012 07:09 PM

Re: casting unsigned int to void*
 
On Monday, July 30, 2012 11:46:51 AM UTC-7, Alan Curry wrote:
> There was some really unforgivable formatting in here, especially the more deeply quoted parts, so I chopped them out. Google Groups sucks! Get a real newsreader! In article <afc78550-acc3-4f3f-b9e6-5dcbe1e33061@googlegroups.com>, Fred K <fred.l.kleinschmidt@gmail.com> wrote: [about xpm] > >Well, it was written a long time ago, and for platforms where the size >of an intwas the same size as a pointer. So far, I haven't found a >problem with iton an HP-UX, SGI, Sun, AIX; I'm now porting it to >several flavors of (64-bit) Linux, and iPad. Time will tell... Xpm isn't some dead artifact you just dug up that nobody else remembers. It has been continuously maintained and is still distributed by x.org. Why can't you use their version? It should already be bundled with your Linux distribution. -- Alan Curry


I just downloaded the current version (including source code) and it still has that code in it, so they are currently using code that may be problematic.

Ben Bacarisse 07-30-2012 08:02 PM

Re: casting unsigned int to void*
 
Fred K <fred.l.kleinschmidt@gmail.com> writes:

> On Monday, July 30, 2012 11:46:51 AM UTC-7, Alan Curry wrote:
>> There was some really unforgivable formatting in here, especially the more deeply quoted parts, so I chopped them out. Google Groups sucks! Get a real newsreader! In article <afc78550-acc3-4f3f-b9e6-5dcbe1e33061@googlegroups.com>, Fred K <fred.l.kleinschmidt@gmail.com> wrote: [about xpm] > >Well, it was written a long time ago, and for platforms where the size >of an int was the same size as a pointer. So far, I haven't found a >problem with it on an HP-UX, SGI, Sun, AIX; I'm now porting it to >several flavors of (64-bit) Linux, and iPad. Time will tell... Xpm isn't some dead artifact you just dug up that nobody else remembers. It has been continuously maintained and is still distributed by x.org. Why can't you use their version? It should already be bundled with your Linux distribution. -- Alan Curry


There is something odd with your quoting! Is this another Google groups
issue?

> I just downloaded the current version (including source code) and it
> still has that code in it, so they are currently using code that may
> be problematic.


The "may" is key. It may be problematic, but I doubt it. It's a very
common trick, and every implementation I've used defines the conversion
in a way that makes recovery of the int (the actual purpose here) safe.

You are doing the porting, are you not? Is it actually a problem?

--
Ben.

James Kuyper 07-30-2012 08:22 PM

Re: casting unsigned int to void*
 
On 07/30/2012 04:04 PM, China Blue [Tor], Meersburg wrote:
....
> intptr_t is an integer which is large enough to hold a void* pointer encoded in
> an integer. This is an ancient bug dating back to the days when an integer was
> 60 bits, would always be 60 bits, and an address was 18 bits, and would always


Your descriptions seem highly platform-specific; I'm not familiar with a
platform that had those particular characteristics. Could you identify it?

> be 18 bits. The 80x86s had addresses (20 bits) larger than ints (16 bits),
> exposing this bad assumption. The intptr_t was eventually introduced to provide
> an integer that would always be safe to hold addresses.




James Kuyper 07-30-2012 10:15 PM

Re: casting unsigned int to void*
 
On 07/30/2012 05:55 PM, China Blue [Tor], Meersburg wrote:
> In article <5016ECE9.3050605@verizon.net>,
> James Kuyper <jameskuyper@verizon.net> wrote:
>
>> On 07/30/2012 04:04 PM, China Blue [Tor], Meersburg wrote:
>> ...
>>> intptr_t is an integer which is large enough to hold a void* pointer
>>> encoded in
>>> an integer. This is an ancient bug dating back to the days when an integer
>>> was
>>> 60 bits, would always be 60 bits, and an address was 18 bits, and would
>>> always

>>
>> Your descriptions seem highly platform-specific; I'm not familiar with a
>> platform that had those particular characteristics. Could you identify it?

>
> http://en.wikipedia.org/wiki/CDC_6600


Can you give us any particular reason to believe that this particular
processor had a major role to play in setting up expectations, relevant
to the design of C, that were later violated by the Intel 8086 family of
processors, as implied by your earlier message? Your wording gave the
impression that 60-bit integers were so widely used that many people
thought they were universal. The article you linked to refers to the
60-bit words as "very large", belying that implication.


All times are GMT. The time now is 04:48 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57