Question about void pointers

K

Keith Thompson

Richard said:
Garbage. On my machine it prints a 32 bit value. Pointers are values
which I can printf and see and they correspond to physical memory
locations. Its a number get over it.

Then why does printf have a "%p" format?

Pointers are not numbers. They are often, but not always, implemented
as numbers, but they are different things. If you don't understand
the difference, you don't understand C; at best, you might have some
understanding of a particular C implementation.

You might as well claim that, for example, 64-bit floating-point
numbers are really 64-bit integers because they're composed of 64
bits.

Pointer arithmetic doesn't mean what you think it means.
 
J

jameskuyper

Richard said:
Richard wrote: ....
And the following:

int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p++);
printf("%u\n",p++);

That is undefined behavior by reason of trying to print an pointer
value using a format string that calls for an unsigned integer. The
behavior is technically meaningless, though in practice it will
produce much the same effect as casting the the pointer value to
unsigned int on many systems. You could have demonstrated your point
without undefined behavior by using uintptr_t; why didn't you?
printf("%u\n", (int)(p - q));

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.

Yes, but that difference has no portable meaning, and the

It has a meaning.

I didn't deny that it had a meaning, only that it didn't have a
portable meaning. In fact, I was quite specific about what meaning it
does have just a few lines later:

Returning to your comments:
... The VALUE of p is incremented by 4. On my machine. And
probably the OPs.

No, your conversion did not access the value of 'p'. It appears to
have accessed the representation of 'p', as an address pointing at a
particular byte in memory. The value of p is the location of a
particular long int in memory. That value has increased by 1, to point
at the next long int in memory.

You're making fundamentally the same mistake as someone who notices
that, on a particular implementation, the representation of 4.0F is
0x40800000, while the representation of 2.0F is 0x40000000, and on the
basis of that fact declares that the difference between 4.0F and 2.0F
is 0x80000. It feels more natural to make this mistake with pointer
values than it does with floating point values. That is because the
connection between pointer representations and pointer values is
typically much simpler than the connection between floating point
representations and floating point values. However, the principle is
exactly the same.
 
R

Richard

Keith Thompson said:
Then why does printf have a "%p" format?

Pointers are not numbers. They are often, but not always, implemented
as numbers, but they are different things. If you don't understand
the difference, you don't understand C; at best, you might have some
understanding of a particular C implementation.

Actually quite a few. I challenge you to find me ONE single
implementation where a pointer is not an integer (no size specified)
value when displayed in a debugger. Do TRY and be realistic. No wonder
so many people think pointers are difficult if you are teaching
them. However some of us reside in the real world.
You might as well claim that, for example, 64-bit floating-point
numbers are really 64-bit integers because they're composed of 64
bits.

But they ARE still numbers. Like it or not. The interpretation depends
on your point of view.
Pointer arithmetic doesn't mean what you think it means.

--
 
S

s0suk3

Then why does printf have a "%p" format?

Pointers are not numbers.

Then how come C99 introduces the intptr_t typedef and the PRIdPTR
conversion specifier to print it as decimal?

Sebastian
 
R

Richard

Richard said:
Richard wrote: ...
And the following:

int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p++);
printf("%u\n",p++);

That is undefined behavior by reason of trying to print an pointer
value using a format string that calls for an unsigned integer. The
behavior is technically meaningless, though in practice it will
produce much the same effect as casting the the pointer value to
unsigned int on many systems. You could have demonstrated your point
without undefined behavior by using uintptr_t; why didn't you?

printf("%u\n", (int)(p - q));

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.

Yes, but that difference has no portable meaning, and the

It has a meaning.

I didn't deny that it had a meaning, only that it didn't have a
portable meaning. In fact, I was quite specific about what meaning it
does have just a few lines later:

So wwhat? I said "on my machine".
Returning to your comments:

No, your conversion did not access the value of 'p'. It appears to
have accessed the representation of 'p', as an address pointing at a
particular byte in memory. The value of p is the location of a
particular long int in memory. That value has increased by 1, to point
at the next long int in memory.

You're making fundamentally the same mistake as someone who notices

I am making no mistake. I understand the abstract view as well as the
real view.

But the debugger does not lie. It was incremented by 4. It has a real
life value. And it was increased by 4. And yes I know it was ONE
conceptual int.
that, on a particular implementation, the representation of 4.0F is
0x40800000, while the representation of 2.0F is 0x40000000, and on the
basis of that fact declares that the difference between 4.0F and 2.0F
is 0x80000. It feels more natural to make this mistake with pointer
values than it does with floating point values. That is because the
connection between pointer representations and pointer values is
typically much simpler than the connection between floating point
representations and floating point values. However, the principle is
exactly the same.

I really do not know who you are trying to convince or confuse. I
challenge you one thing. Explain how, on may machine, p++ has not
increased the value of p by 4 when the values are quite clearly

by all means explain to people the "logical increase of one" when
referring to a pointer to ints but please do not insult anyones
intelligence by denying the value has increased, in this case by 4.

We could go around for years. I have programmed in C (amongst other
things) for years. I know what you are inferring but please do not lose
sight of the real world. And in teh real world

3214862940 - 3214862936 is 4
 
K

Keith Thompson

Then how come C99 introduces the intptr_t typedef and the PRIdPTR
conversion specifier to print it as decimal?

Because pointers can be *converted* to numbers. Note that intptr_t
doesn't necessarily exist; in particular, it won't exist if there is
no integer type big enough to hold the converted value of a pointer
without loss of information.

Similarly, the floating-point value 42.3 can be converted to the
integer value 42, but that doesn't mean that 42.3 is an integer value.
Nor is 42.0 an integer value, even though it happens that it can be
converted to an integer value with no loss of information.

On many implementations, conversions between pointers and
appropriately-sized integers, or between pointers and pointers, happen
to be trivial, involving just a reinterpretation of the same
represenatation. Because of this you can sometimes get away with the
invalid assumption that pointers are just integers.

And sometimes you actually *need* to treat pointers as integers, when
you're writing low-level system-specific code. For example, I presume
that a typical malloc implementation has to do this kind of thing to
ensure that the resulting pointer value is properly aligned. But
nothing we've been discussing in this thread requires that kind of
low-level system-specific code.
 
J

jameskuyper

Richard said:
Actually quite a few. I challenge you to find me ONE single
implementation where a pointer is not an integer (no size specified)
value when displayed in a debugger. Do TRY and be realistic. No wonder
so many people think pointers are difficult if you are teaching
them. However some of us reside in the real world.


But they ARE still numbers. Like it or not. The interpretation depends
on your point of view.


--
 
J

jameskuyper

Richard said:
So wwhat? I said "on my machine".

And I said "portable". Unless you are confusing "portable" with "on my
machine", I gave you no grounds for saying "it has meaning", as if I
had somehow implied that it didn't have meaning.

I really do not know who you are trying to convince or confuse. I
challenge you one thing. Explain how, on may machine, p++ has not
increased the value of p by 4 when the values are quite clearly

Because adding the following code fragments in the appropriate
locations in your program:

#include <inttypes.h>
....
printf("Difference:%" PRIiPTR "\n", p-q);

produces the following result:

Difference:1

and not

Difference:4

....
sight of the real world. And in teh real world

3214862940 - 3214862936 is 4

And in the real world, p-q is 1.
 
K

Keith Thompson

Richard said:
Actually quite a few. I challenge you to find me ONE single
implementation where a pointer is not an integer (no size specified)
value when displayed in a debugger.

No.

You're the one making the claim that pointers are numbers. Prove it.
And please remember that we're discussing this in the context of the C
language, not in some all-the-world's-a-VAX^H^H^Hx86 fantasy land.
But they ARE still numbers. Like it or not. The interpretation depends
on your point of view.

Yes, of course they're numbers. But they're not integers.

Someone who makes the false claim that pointers are really numbers is
almost certainly claiming that they're integers. Pointers are
integers in the same way that floating-point numbers are integers
(i.e., they're not).

As you continue to demonstrate.
 
J

jameskuyper

(e-mail address removed) wrote:
....
Because adding the following code fragments in the appropriate
locations in your program:

#include <inttypes.h>
...
printf("Difference:%" PRIiPTR "\n", p-q);

That's what comes from hurrying; I looked up how to print intptr_t
values, rather than ptrdiff_t values. It should have been much
simpler:

printf("Difference:%td\n", p-q);gr
 
J

Jean-Marc Bourguet

Richard said:
Actually quite a few. I challenge you to find me ONE single
implementation where a pointer is not an integer (no size specified)
value when displayed in a debugger.

x86 "real mode"? far pointer are usually printed as seg:eek:ffset on that
architecture. There have been several implementations for that
architecture.

For the fun, I've also this machine to which I telnetted to run a little
program. That may interest you:

@type pvoid.c
#include <stdio.h>

int main()
{
int x;
char y;
char t[10];
int i;
printf("&x = %p\n&x = %o\n&y = %p\n", (void*)&x, (unsigned)&x, (void*)&y);
for (i=0; i<10; ++i) {
printf("&t[%d] = %p\n", i, &t);
}
return 0;
}
@run pvoid
&x = 331100050105
&x = 50105
&y = 1100050106
&t[0] = 331100050107
&t[1] = 221100050107
&t[2] = 111100050107
&t[3] = 1100050107
&t[4] = 331100050110
&t[5] = 221100050110
&t[6] = 111100050110
&t[7] = 1100050110
&t[8] = 331100050111
&t[9] = 221100050111

pointers are printed as number here, but they probably don't behave like
you'd expect. BTW, a debugger would have printed the first and third as
331100,,50105 and 1100,,50106. To understand the void* one, you have to
know that those are byte pointers, pointing to bytes made of 9 bits (11
octal is 9 decimal, octal being the base commonly use on this 36 bits
machines) inside 36 bits words. Those starting by 33 are pointing to the
least significant 9 bit byte of the word (starting at bit 33 octal -- 27 in
decimal).

Admitly this is quite an older machine, but at a time it was the most
common architecture on the Arpanet. The one I telnetted to was an emulated
one, but there are still some hardware one on the Internet. There is also
gcc 4.3 port for it, and I suspect the company which is paying to make that
port still makes hardware implementation even if it doesn't sell them
outside systems.
Do TRY and be realistic. No wonder so many people think pointers are
difficult if you are teaching them. However some of us reside in the real
world.

The world is more diverse that you think?
But they ARE still numbers. Like it or not. The interpretation depends on
your point of view.

You can consider any bit pattern as a number, but when it is an address
that is not always the best thing to do.

Yours,
 
V

vippstar

@type pvoid.c
#include <stdio.h>

int main()
{
int x;
char y;
char t[10];
int i;
printf("&x = %p\n&x = %o\n&y = %p\n", (void*)&x, (unsigned)&x, (void*)&y);
for (i=0; i<10; ++i) {
printf("&t[%d] = %p\n", i, &t);
}
return 0;}


I'm curious, why don't you cast &t to (void *)?
My thoughts: &t is a char *. void * and char * are guaranteed to
have the same representation and size.
However, does that let you pass char * to a variadic function
expecting void *? (there's probably not a singlest implementation
where it'd matter, but I'm curious)
 
S

s0suk3

     Perhaps you should be more specific about what you mean by "this
kind of task," because I (mis?)understood you to be referring to the
code in the original post.

I was referring to the task of performing pointer arithmetic on a void
pointer rather than on an unsigned char pointer, in a case where the
pointer points to some arbitrary object (an array of int, in the OP's
case).
     So you understand English as well as you understand C?

....says someone who made a remark about something without being aware
of what he was talking about. Seriously, though, I don't know what you
mean by me "being on the ballot a couple of weeks from now" or me
"choosing my running mate yet."

Sebastian
 
K

Kenny McCormack

Richard said:
Actually quite a few. I challenge you to find me ONE single
implementation where a pointer is not an integer (no size specified)
value when displayed in a debugger. Do TRY and be realistic. No wonder
so many people think pointers are difficult if you are teaching
them. However some of us reside in the real world.

Your points are, of course, valid as always.

Still, I hear that AIX machines have this funny kind of pointers, that
are not at all like their integers.

Also, DOS in the various memory models.

But, of course, this isn't what you mean. I actually do know what you
mean, and the above text was just me pretending to be that idiot KT.

My goal is to try to get you to understand the crazy, mixed up world of
Keith Thompson. Be sure to wear your seat belts; it is going to be a
rough ride...
 
K

Keith Thompson

Richard said:
I really do not know who you are trying to convince or confuse. I
challenge you one thing. Explain how, on may machine, p++ has not
increased the value of p by 4 when the values are quite clearly

You're not looking at the value of p. You're looking at the
representation of p, interpreted as if it were an integer.

Similarly, when I run this program:

#include <stdio.h>
int main(void)
{
double x = 42.0;
double y = x;
y ++;
printf("x = %llu\n", x);
printf("y = %llu\n", y);
return 0;
}

I get this output:

x = 4631107791820423168
y = 4631248529308778496

By your logic, the value of y has clearly increased by 140737488355328.

The representation of a floating-point object can sometimes be viewed
as if it were an integer object, but we typically don't do that
because it doesn't make sense.

The representation of a pointer object can sometimes be viewed as if
it were an integer object, and doing so can *sometimes* be useful if
you're concerned about machine-level issues. But it's perfectly
feasible to write C programs making use of pointers without even being
aware of how they're represented.

I don't much care whether you understand this or not. I'm replying to
you for the benefit of other readers who might be misled by your
sloppy thinking.
 
R

Richard

Keith Thompson said:
[snip]
You're using "%u" to print pointer values.  Surely you know that
invokes undefined behavior, and I know of common real-world systems

Garbage. On my machine it prints a 32 bit value. Pointers are values
which I can printf and see and they correspond to physical memory
locations. Its a number get over it.

Then why does printf have a "%p" format?

Pointers are not numbers.

Then how come C99 introduces the intptr_t typedef and the PRIdPTR
conversion specifier to print it as decimal?

Because pointers can be *converted* to numbers. Note that intptr_t

My pointers were numbers. I could see them in the debugger....
 
R

Richard

Your points are, of course, valid as always.

Still, I hear that AIX machines have this funny kind of pointers, that
are not at all like their integers.

Also, DOS in the various memory models.

But, of course, this isn't what you mean. I actually do know what you
mean, and the above text was just me pretending to be that idiot KT.

My goal is to try to get you to understand the crazy, mixed up world of
Keith Thompson. Be sure to wear your seat belts; it is going to be a
rough ride...

No. I'm done with this thread. He knows I know about the abstract
concept. But like Falconer unless you specify everything they take the
opportunity to belittle and treat you like an imbecile with their
posturing and pontificating.

But which ever way you look at those pointers were numbers held in a
register and subtracted gave 4.

To deny it is simply crazy.
 
C

CBFalconer

.... snip ...


I was referring to the task of performing pointer arithmetic on a
void pointer rather than on an unsigned char pointer, in a case
where the pointer points to some arbitrary object (an array of int,
in the OP's case).

You aren't allowed to do that. Just read the C standard.

Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://c-faq.com/> (C-faq)
<http://benpfaff.org/writings/clc/off-topic.html>
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf> (C99)
<http://cbfalconer.home.att.net/download/n869_txt.bz2> (C99, txt)
<http://www.dinkumware.com/c99.aspx> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
<http://clc-wiki.net/wiki/C_community:comp.lang.c:Introduction>
 
R

Richard

CBFalconer said:
You aren't allowed to do that. Just read the C standard.

Or if you dont have the time to wade through that Wikipedia has a nice
article complete with compare and contrast to other languages.

http://en.wikipedia.org/wiki/Pointer

In gcc you can perform arithmetic on void pointers as it assumes
unsigned char *. Which is common sense IMO in 99.9999% of platforms
since real memory is address at real memory addresses which are real
numbers.

--
 
C

CBFalconer

Richard said:
Keith Thompson said:
[snip]

You're using "%u" to print pointer values. Surely you know that
invokes undefined behavior, and I know of common real-world systems

Garbage. On my machine it prints a 32 bit value. Pointers are values
which I can printf and see and they correspond to physical memory
locations. Its a number get over it.

Then why does printf have a "%p" format?

Pointers are not numbers. They are often, but not always, implemented
as numbers, but they are different things. If you don't understand
the difference, you don't understand C; at best, you might have some
understanding of a particular C implementation.

Actually quite a few. I challenge you to find me ONE single
implementation where a pointer is not an integer (no size specified)
value when displayed in a debugger. Do TRY and be realistic. No wonder
so many people think pointers are difficult if you are teaching
them. However some of us reside in the real world.

Piggy-backing, because Richard is PLONKed here. However this post
is full of misinformation.

There are lots of such implementations, such as anything that runs
under MsDOS. All malloc has to do is find some place to store
information. This may involve selecting a school, a grade, and a
small boy within that grade to hold a piece of paper. The pointer
will contain the information about school, grade, small boy, and
which piece of paper. malloc allocates storage, not necessarily
conventional memory.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top