[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Passing an integer to a function that accepts a void pointer

pozz

5/11/2011 10:02:00 AM

What do you think about this code?

int foo(const void *Args) {
printf("%d\n", (const int)Args);
return 0;
}

int main(int argc, char *argv[]) {
foo((void *)10);
return 0;
}

It seems work and it should be nice if it is a sufficient portable way
to pass integers as pointers.

Why don't I declare foo() to directly accept int? Because it is a
callback of a library I can't change and the prototype of the callback
is well defined by the library to accept void pointer.
61 Answers

Tom St Denis

5/11/2011 10:52:00 AM

0

On May 11, 6:01 am, pozz <pozzu...@gmail.com> wrote:
> What do you think about this code?
>
> int foo(const void *Args) {
>   printf("%d\n", (const int)Args);
>   return 0;
>
> }
>
> int main(int argc, char *argv[]) {
>   foo((void *)10);
>   return 0;
>
> }
>
> It seems work and it should be nice if it is a sufficient portable way
> to pass integers as pointers.
>
> Why don't I declare foo() to directly accept int? Because it is a
> callback of a library I can't change and the prototype of the callback
> is well defined by the library to accept void pointer.

Why not just do this

int bar = 10;
foo(&bar);

And inside foo do

printf("%d\n", *((int *)Args));

That way the program is actually portable.

Tom


China Blue Veins

5/11/2011 11:03:00 AM

0

In article <80905e4d-6b11-4843-b4e7-96f0c7db8b23@l18g2000yql.googlegroups.com>,
pozz <pozzugno@gmail.com> wrote:

> What do you think about this code?

stdint.h defines a type name intptr_t which is an integer that can be converted
to a pointer and back again:
void *p = ...; intptr_t a = ...;

a is an integer variable and you can use << >> % etc with it.

(void*)(intptr_t)p == p
(intptr_t)(void*)a == a

p = (void*)a;

(intptr_t)p == a
p == (void*)a


> int foo(const void *Args) {
> printf("%d\n", (const int)Args);
> return 0;
> }
>
> int main(int argc, char *argv[]) {
> foo((void *)10);
> return 0;
> }
>
> It seems work and it should be nice if it is a sufficient portable way
> to pass integers as pointers.
>
> Why don't I declare foo() to directly accept int? Because it is a
> callback of a library I can't change and the prototype of the callback
> is well defined by the library to accept void pointer.

--
Damn the living - It's a lovely life. I'm whoever you want me to be.
Silver silverware - Where is the love? At least I can stay in character.
Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
Damn the living - It's a lovely life. In 1492....

Eric Sosman

5/11/2011 11:38:00 AM

0

On 5/11/2011 6:01 AM, pozz wrote:
> What do you think about this code?

Nothing good.

> int foo(const void *Args) {
> printf("%d\n", (const int)Args);
> return 0;
> }
>
> int main(int argc, char *argv[]) {
> foo((void *)10);
> return 0;
> }
>
> It seems work and it should be nice if it is a sufficient portable way
> to pass integers as pointers.

It's not portable. Both the integer-to-pointer conversion in
the call and the pointer-to-integer conversion in the function are
implementation-defined, and the implementation is not required to
define them as inverses of each other. Many will so define them,
but it's not guaranteed. I've run into implementations that swizzle
the values on some integer/pointer/integer conversions, although to
be truthful I've only seen it with things like double* pointers, not
with void*.

> Why don't I declare foo() to directly accept int? Because it is a
> callback of a library I can't change and the prototype of the callback
> is well defined by the library to accept void pointer.

Pthreads, perhaps? No matter: take Tom St Denis' advice and pass
a pointer to an int variable holding the desired value.

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

pete

5/11/2011 12:11:00 PM

0

Tom St Denis wrote:
>
> On May 11, 6:01 am, pozz <pozzu...@gmail.com> wrote:
> > What do you think about this code?
> >
> > int foo(const void *Args) {
> > printf("%d\n", (const int)Args);
> > return 0;
> >
> > }
> >
> > int main(int argc, char *argv[]) {
> > foo((void *)10);
> > return 0;
> >
> > }
> >
> > It seems work and it should be nice if it is a sufficient portable way
> > to pass integers as pointers.
> >
> > Why don't I declare foo() to directly accept int? Because it is a
> > callback of a library I can't change and the prototype of the callback
> > is well defined by the library to accept void pointer.
>
> Why not just do this
>
> int bar = 10;
> foo(&bar);
>
> And inside foo do
>
> printf("%d\n", *((int *)Args));
>
> That way the program is actually portable.

That's what I was thinking too.

--
pete

Heikki Kallasjoki

5/11/2011 1:04:00 PM

0

On 2011-05-11, Columbus sailed the ocean China Blue <chine.bleu@yahoo.com> wrote:
> In article <80905e4d-6b11-4843-b4e7-96f0c7db8b23@l18g2000yql.googlegroups.com>,
> pozz <pozzugno@gmail.com> wrote:
>
>> What do you think about this code?
>
> stdint.h defines a type name intptr_t which is an integer that can be converted
> to a pointer and back again:
> void *p = ...; intptr_t a = ...;
>
> a is an integer variable and you can use << >> % etc with it.
>
> (void*)(intptr_t)p == p
> (intptr_t)(void*)a == a

The above is not entirely true. The intptr_t and uintptr_t types, if
they exist (they are optional), are capable of holding any valid
pointer-to-void value, but not the other way around. To quote the
C99 draft,

"The following type [intptr_t] designates a signed integer type with the
property that any valid pointer to void can be converted to this type,
then converted back to pointer to void, and the result will compare
equal to the original pointer"

In other words, the conversion to intptr_t and back is safe only for
valid pointers. Arbitrary integer values, even if they are stored in an
intptr_t object, are not guaranteed to be safely convertible to
pointers.

--
Heikki Kallasjoki
email: echo 'zfs+es_t_i@n_u.zf' | tr zen_muftis fuze_mints

James Kuyper

5/11/2011 1:43:00 PM

0

On 05/11/2011 06:01 AM, pozz wrote:
> What do you think about this code?
>
> int foo(const void *Args) {
> printf("%d\n", (const int)Args);
> return 0;
> }
>
> int main(int argc, char *argv[]) {
> foo((void *)10);
> return 0;
> }
>
> It seems work and it should be nice if it is a sufficient portable way
> to pass integers as pointers.

It isn't portable. For the cast to void*: "... the result is
implementation-defined, ... and might be a trap representation."
(6.3.2.3p5). For the conversion back to int: "... the result is
implementation-defined. If the result cannot be represented in the
integer type, the behavior is undefined. The result need not be in the
range of values of any integer type." (6.3.2.3p6)

Note that the best you can hope for, as a result of either conversion,
is an implementation-defined result; there's nothing guaranteeing that
the implementation will define those results in such a way as to produce
a value of 10 (though it's not particularly unusual for them to do so -
that is why your defective code appears to be working).

> Why don't I declare foo() to directly accept int? Because it is a
> callback of a library I can't change and the prototype of the callback
> is well defined by the library to accept void pointer.

Just create an object containing the value 10, and then pass a pointer
to that object. That's how the pointer parameter of the callback
function is intended to be used.
--
James Kuyper

China Blue Veins

5/11/2011 1:47:00 PM

0

In article <slrnisl271.p2s.fis@iris.zem.fi>,
Heikki Kallasjoki <see@end.of.message.invalid> wrote:

> On 2011-05-11, Columbus sailed the ocean China Blue <chine.bleu@yahoo.com>
> wrote:
> > In article
> > <80905e4d-6b11-4843-b4e7-96f0c7db8b23@l18g2000yql.googlegroups.com>,
> > pozz <pozzugno@gmail.com> wrote:
> >
> >> What do you think about this code?
> >
> > stdint.h defines a type name intptr_t which is an integer that can be
> > converted
> > to a pointer and back again:
> > void *p = ...; intptr_t a = ...;
> >
> > a is an integer variable and you can use << >> % etc with it.
> >
> > (void*)(intptr_t)p == p
> > (intptr_t)(void*)a == a
>
> The above is not entirely true. The intptr_t and uintptr_t types, if
> they exist (they are optional), are capable of holding any valid
> pointer-to-void value, but not the other way around. To quote the
> C99 draft,
>
> "The following type [intptr_t] designates a signed integer type with the
> property that any valid pointer to void can be converted to this type,
> then converted back to pointer to void, and the result will compare
> equal to the original pointer"
>
> In other words, the conversion to intptr_t and back is safe only for
> valid pointers. Arbitrary integer values, even if they are stored in an
> intptr_t object, are not guaranteed to be safely convertible to
> pointers.

That's nice. Any compiler that screws this up will break so much software that
it will be rejected.

--
Damn the living - It's a lovely life. I'm whoever you want me to be.
Silver silverware - Where is the love? At least I can stay in character.
Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
Damn the living - It's a lovely life. In 1492....

Keith Thompson

5/11/2011 3:25:00 PM

0

Columbus sailed the ocean China Blue <chine.bleu@yahoo.com> writes:
> In article <slrnisl271.p2s.fis@iris.zem.fi>,
> Heikki Kallasjoki <see@end.of.message.invalid> wrote:
[...]
>> The above is not entirely true. The intptr_t and uintptr_t types, if
>> they exist (they are optional), are capable of holding any valid
>> pointer-to-void value, but not the other way around. To quote the
>> C99 draft,
>>
>> "The following type [intptr_t] designates a signed integer type with the
>> property that any valid pointer to void can be converted to this type,
>> then converted back to pointer to void, and the result will compare
>> equal to the original pointer"
>>
>> In other words, the conversion to intptr_t and back is safe only for
>> valid pointers. Arbitrary integer values, even if they are stored in an
>> intptr_t object, are not guaranteed to be safely convertible to
>> pointers.
>
> That's nice. Any compiler that screws this up will break so much
> software that it will be rejected.

I'm sure there's plenty of software that assumes it can safely
convert integers to pointers. Much of it probably does so
unnecessarily, and much of it makes non-portable assumptions about
the relative sizes of integer and pointer types, and is likely to
break on 64-bit systems. I suspect that most programmers who are
aware of the existence of intptr_t and uintptr_t are experienced
enough to know that they're rarely the right solution.

But how much software depends on being able to convert arbitrary
integer values to pointers? Why would you even want to do that?

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

China Blue Veins

5/11/2011 3:44:00 PM

0

In article <lnhb91l0p9.fsf@nuthaus.mib.org>, Keith Thompson <kst-u@mib.org>
wrote:

> But how much software depends on being able to convert arbitrary
> integer values to pointers? Why would you even want to do that?

Most callback interfaces designed in the last dozens of years depend on that.

--
Damn the living - It's a lovely life. I'm whoever you want me to be.
Silver silverware - Where is the love? At least I can stay in character.
Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
Damn the living - It's a lovely life. In 1492....

Datesfat Chicks

5/11/2011 3:54:00 PM

0

On Wed, 11 May 2011 03:01:49 -0700 (PDT), pozz <pozzugno@gmail.com>
wrote:

>What do you think about this code?
>
>int foo(const void *Args) {
> printf("%d\n", (const int)Args);
> return 0;
>}
>
>int main(int argc, char *argv[]) {
> foo((void *)10);
> return 0;
>}
>
>It seems work and it should be nice if it is a sufficient portable way
>to pass integers as pointers.
>
>Why don't I declare foo() to directly accept int? Because it is a
>callback of a library I can't change and the prototype of the callback
>is well defined by the library to accept void pointer.

I must be missing something.

What library callback are you referring to?

DFC