473,416 Members | 1,713 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

Question about void pointers

Is this valid?

int a[20];
void *b;

b = (void *)a; // b points to a[0]

b += 5*sizeof(*a); // b points to a[5]

a[5] = 100;

printf( "%d\n" , *((int *)b) ); // prints 100

If so, if a had been a struct, would it still work?

Is there a possibility that the array could contain some padding, so
rather than sizeof, the assignment would be

b += 5*( (void *)(&(a[1])) - (void *)(&(a[0]));

which seems more more complex.

Would any padding be incorporated into sizeof anyway?
Sep 16 '08 #1
160 5460
On Sep 16, 6:15 pm, raph...@gmail.com wrote:
Is this valid?

int a[20];
void *b;

b = (void *)a; // b points to a[0]
No need for the cast.
b += 5*sizeof(*a); // b points to a[5]
No, it's not valid. you can not perform arithmetic operations on void
* pointers.
If it compiles, it's because you have extensions enabled. Extensions
are topical to the newsgroup dedicated to the compiler that makes use
of them.
Assuming you had something like

b = ((unsigned char *)b) + 5 * sizeof *a;

Yes, that would be ok.
a[5] = 100;

printf( "%d\n" , *((int *)b) ); // prints 100
Yes, that is valid. Assuming you use my fixes.
If so, if a had been a struct, would it still work?
Yes, but by using the offsetof() macro in <stddef.h>
Is there a possibility that the array could contain some padding, so
rather than sizeof, the assignment would be
No. Arrays don't have padding bytes.
b += 5*( (void *)(&(a[1])) - (void *)(&(a[0]));

which seems more more complex.

Would any padding be incorporated into sizeof anyway?
Yes, sizeof reports the size of an object. Padding bits & bytes belong
to the size of the object.

if sizeof (unsigned int) == 4 and CHAR_BIT == 8, it doesn't mean
unsigned int has 32 value bits.
It might have 16 or less padding bits. (but not more, because of the
guarantee that UINT_MAX >= 65535)
Sep 16 '08 #2
On Sep 16, 8:15*pm, raph...@gmail.com wrote:
Is this valid?

int a[20];
void *b;

b = (void *)a; *// b points to a[0]

b += 5*sizeof(*a); // b points to a[5]

a[5] = 100;

printf( "%d\n" , *((int *)b) ); // prints 100

If so, if a had been a struct, would it still work?

Is there a possibility that the array could contain some padding, so
rather than sizeof, the assignment would be

b += 5*( (void *)(&(a[1])) - (void *)(&(a[0]));

which seems more more complex.

Would any padding be incorporated into sizeof anyway?

b += 5*sizeof(*a); // b points to a[5]
is *incorrect*

when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.
--void *p; p++ //incorrect ==because compiler doesn't know by what
amount should it increase.

the number by which a pointer value is incremented or decremented is
dependent on type of object pointer is pointing to. This number has a
specific name which i don't remember, but this thing is not defined
for void *

b += 5*( (void *)(&(a[1])) - (void *)(&(a[0]));
here also "+=" operation will be invalid due to pointer
moreover there is no padding in between the arrays.

--
vIpIn


Sep 16 '08 #3
On Sep 16, 7:13 pm, sh.vi...@gmail.com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.
Wrong, assuming x was initialized, it would be incremented by 1.

Here's proof:

long int i[1], *p = i, *q = &i[1];
printf("%d\n", (int)(q - p));

Will always print 1.
Sep 16 '08 #4
ra*****@gmail.com writes:
int a[20];
void *b;

b = (void *)a; // b points to a[0]

b += 5*sizeof(*a); // b points to a[5]
This is incorrect, but it will work if you are using GCC in its
default mode, because GCC assumes that "void" has size 1 for the
purpose of pointer arithmetic. If you want to write code that
conforms to the ANSI C standard, you should give GCC appropriate
options to turn off this feature (-Wpointer-arith or -pedantic).
--
Ben Pfaff
http://benpfaff.org
Sep 16 '08 #5
vi******@gmail.com writes:
On Sep 16, 7:13 pm, sh.vi...@gmail.com wrote:
>when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.
Even if it wasnt initialised it would be incremented by something.
>
Here's proof:
Proof of nothing. You are, again, being purposely difficult.
>
long int i[1], *p = i, *q = &i[1];
printf("%d\n", (int)(q - p));

Will always print 1.
And the following:

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

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.
Sep 16 '08 #6
sh******@gmail.com writes:
On Sep 16, 8:15*pm, raph...@gmail.com wrote:
>Is this valid?

int a[20];
void *b;
[...]
>
b += 5*sizeof(*a); // b points to a[5]
is *incorrect*
Yes.
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.
--void *p; p++ //incorrect ==because compiler doesn't know by what
amount should it increase.

the number by which a pointer value is incremented or decremented is
dependent on type of object pointer is pointing to. This number has a
specific name which i don't remember, but this thing is not defined
for void *
You're probably thinking of "stride", though the standard doesn't use
that term.

However, some compilers (particularly gcc) allow arithmetic on void*
as an extension, treating the stride as 1 byte. In my opinion this
extension is a bad idea; it can be convenient, but it doesn't give you
anything you can't do by other means, it has some bizarre
consequences, and as we've seen here it can make it easy to write
non-portable code without realizing it.

If you invoke gcc with the right options (something like "-ansi
-pedantic -Wall -Wextra") it will at least warn you about any attempts
to use this extension.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #7
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly.
Yes, but by using the offsetof() macro in <stddef.h>
I meant to point to the structure.

struct st { int val; } a[100];

void *b;

a[5].val = 100;

b = a;
b = ((unsigned char *)b) + 5 * sizeof *a;

printf( "%d\n" , b->val );
Sep 16 '08 #8
On Sep 16, 5:51 pm, raph...@gmail.com wrote:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;

I see, got to switch to char * so that it can be incremented properly.
Yes, but by using the offsetof() macro in <stddef.h>

I meant to point to the structure.

struct st { int val; } a[100];

void *b;

a[5].val = 100;

b = a;
b = ((unsigned char *)b) + 5 * sizeof *a;

printf( "%d\n" , b->val );

or at least

printf( "%d\n" , ((struct st *)b)->val );
Sep 16 '08 #9
On Sep 16, 11:51*am, ra*****@gmail.com wrote:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
>b = ((unsigned char *)b) + 5 * sizeof *a;

I see, got to switch to char * so that it can be incremented properly.
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.

Sebastian

Sep 16 '08 #10
On Sep 16, 7:59 pm, s0s...@gmail.com wrote:
On Sep 16, 11:51 am, raph...@gmail.com wrote:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly.

No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Sep 16 '08 #11
On Sep 16, 12:06*pm, vi******@gmail.com wrote:
On Sep 16, 7:59 pm, s0s...@gmail.com wrote:
On Sep 16, 11:51 am, raph...@gmail.com wrote:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
>b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly..
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.

You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.

Sebastian

Sep 16 '08 #12
vi******@gmail.com writes:
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
I admit that, occasionally, I've used pointer arithmetic on void
* in cases where GCC is the only compiler that matters. (Code
inside the Linux kernel is one example.) The nice thing about
doing it that way is that it avoids having to insert additional
casts, which are ugly.

I wouldn't do it in a place where portability matters.
--
"To get the best out of this book, I strongly recommend that you read it."
--Richard Heathfield
Sep 16 '08 #13
Richard<rg****@gmail.comwrites:
vi******@gmail.com writes:
>On Sep 16, 7:13 pm, sh.vi...@gmail.com wrote:
>>when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.
If x isn't initialized, referring to its value invokes undefined
behavior. It's likely, but by no means certain, that the behavior
would be *as if* it were incremented. It's also possible, on some
systems, that x could have a value such that attempting to read it
causes a program crash. (Before you ask, no, I don't have an
example.)
>Here's proof:

Proof of nothing. You are, again, being purposely difficult.
The ++ operator increments its operand by 1, by definition. The
question is, 1 what? In the case of:

long int *x = some_value;
x ++;

it advances it by 1 long int object, i.e., causes it to point to the
next adjacent long int object in memory, assuming that such an object
exists; it can also legally point just past the end of an array.
>long int i[1], *p = i, *q = &i[1];
Note that evaluating &i[1] is ok, and equivalent to i+1, but only
because of a special-case rule; see C99 6.5.3.2p3.
>printf("%d\n", (int)(q - p));

Will always print 1.
Yes, because of the way pointer subtraction is defined.
And the following:

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

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.
You're using "%u" to print pointer values. Surely you know that
invokes undefined behavior, and I know of common real-world systems
where it won't work (e.g., where int is 32 bits and pointers are 64
bits). You're also using "%u" to print an int value; if you had
written
printf("%u\n", (unsigned)(p - q));
that wouldn't be no problem. (Actually printing a non-negative int
value using %u is probably ok, due to another special-case rule, but
there's no point in taking advantage of that fact.) Finally, p starts
as a pointer to the first and only element of a 1-element array. You
increment it twice, causing it to point *past* the end of the array.
Yet another instance of undefined behavior that happens to "work" on
your system -- and it wasn't even necessary to demonstrate your point.

You're making unwarranted (though commonly valid) assumptions about
pointer representations and conversions. This program:

#include <stdio.h>
int main(void)
{
long array[10];
long *p = &array[0];
long *q = &array[1];
printf("%d %d %d\n",
(int)sizeof(long), (int)(q - p), (int)q - (int)p);
return 0;
}

will typically print "4 1 4" on a system where sizeof(long)==4. I've
worked on a real-world system where it would print "8 1 1" due to a
rather unusual pointer representation.

And the thing is, all this undefined behavior wasn't even necessary to
demonstrate your point. Here's a portable program (with
implementation-defined but not undefined behavior) that illustrates
what you're trying to talk about:

#include <stdio.h>
#include <assert.h>
int main(void)
{
long array[10];
long *p = &array[0];
long *q = &array[1];
int diff = q - p;
int byte_diff = (char*)q - (char*)p;
printf("p = %p\n", (void*)p);
printf("q = %p\n", (void*)q);
printf("sizeof(long) = %d\n", (int)sizeof(long));
printf("diff = %d\n", diff);
printf("byte_diff = %d\n", byte_diff);
assert(diff == 1);
assert(byte_diff == sizeof(long));
return 0;
}

On my system, I get:

p = 0xbfce19ac
q = 0xbfce19b0
sizeof(long) = 4
diff = 1
byte_diff = 4

And here's the point:

p++ increments p by 1. If p is a long*, this means that it advances
the memory location to which it points by 1 long, or by sizeof(long)
bytes.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #14
Richard wrote:
vi******@gmail.com writes:
On Sep 16, 7:13 pm, sh.vi...@gmail.com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.
Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.
On real, widely used machines, attempting to access an unitialized
pointer value can cause your program to abort before that value ever
gets a chance to be incremented.

....
long int i[1], *p = i, *q = &i[1];
printf("%d\n", (int)(q - p));

Will always print 1.

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
implementation-specific meaning on your machine is (probably) only
that p and q point at locations 4 bytes apart; that doesn't say
anything about how much has been added to q to get the current value
of p.

It is only the third printf() that provides a meaningful answer to the
question of how big the difference is between p and q is. You'll get a
different answer, if you cast both pointer to char* before subtracting
them. On your machine that answer will probably be 4, but that answer
is to a different question,
Sep 16 '08 #15
ra*****@gmail.com writes:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
>b = ((unsigned char *)b) + 5 * sizeof *a;

I see, got to switch to char * so that it can be incremented properly.
>Yes, but by using the offsetof() macro in <stddef.h>

I meant to point to the structure.

struct st { int val; } a[100];

void *b;

a[5].val = 100;

b = a;
b = ((unsigned char *)b) + 5 * sizeof *a;

printf( "%d\n" , b->val );
If you want to point to a structure, why not just use a
pointer-to-structure rather than a pointer-to-void?

But if you must use void* for some reason, I think this is more
straightforward:

b = (struct st*)b + 5;

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #16
On Sep 16, 9:46*pm, Keith Thompson <ks...@mib.orgwrote:
sh.vi...@gmail.com writes:
On Sep 16, 8:15*pm, raph...@gmail.com wrote:
Is this valid?

*In my opinion this
extension is a bad idea; it can be convenient, but it doesn't give you
anything you can't do by other means, it has some bizarre
consequences,

I think Bus Error,on some machines, is one of those consequences.
Thanks all for gcc info. I thought gcc didn't take anything as stride
value for void pointers
--
vIpIn
Sep 16 '08 #17
Keith Thompson <ks***@mib.orgwrites:
Richard<rg****@gmail.comwrites:
>vi******@gmail.com writes:
>>On Sep 16, 7:13 pm, sh.vi...@gmail.com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.

If x isn't initialized, referring to its value invokes undefined
behavior. It's likely, but by no means certain, that the behavior
would be *as if* it were incremented. It's also possible, on some
systems, that x could have a value such that attempting to read it
causes a program crash. (Before you ask, no, I don't have an
example.)
Whatever. x will be incremented.
>
>>Here's proof:

Proof of nothing. You are, again, being purposely difficult.

The ++ operator increments its operand by 1, by definition. The
question is, 1 what? In the case of:

long int *x = some_value;
x ++;

it advances it by 1 long int object, i.e., causes it to point to the
next adjacent long int object in memory, assuming that such an object
exists; it can also legally point just past the end of an array.
>>long int i[1], *p = i, *q = &i[1];

Note that evaluating &i[1] is ok, and equivalent to i+1, but only
because of a special-case rule; see C99 6.5.3.2p3.
>>printf("%d\n", (int)(q - p));

Will always print 1.

Yes, because of the way pointer subtraction is defined.
>And the following:

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

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.

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.
Sep 16 '08 #18
ja*********@verizon.net writes:
Richard wrote:
>vi******@gmail.com writes:
On Sep 16, 7:13 pm, sh.vi...@gmail.com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.

On real, widely used machines, attempting to access an unitialized
pointer value can cause your program to abort before that value ever
gets a chance to be incremented.
Never come across it. Which machines? I do believe you btw. However in
the great majority (99.9999%= of machines on this planet it will indeed
by incremented.
>
...
long int i[1], *p = i, *q = &i[1];
printf("%d\n", (int)(q - p));

Will always print 1.

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. The VALUE of p is incremented by 4. On my machine. And
probably the OPs.
implementation-specific meaning on your machine is (probably) only
that p and q point at locations 4 bytes apart; that doesn't say
anything about how much has been added to q to get the current value
of p.

It is only the third printf() that provides a meaningful answer to the
question of how big the difference is between p and q is. You'll get a
different answer, if you cast both pointer to char* before subtracting
them. On your machine that answer will probably be 4, but that answer
is to a different question,
--
Sep 16 '08 #19
s0****@gmail.com wrote:
On Sep 16, 12:06 pm, vi******@gmail.com wrote:
>On Sep 16, 7:59 pm, s0s...@gmail.com wrote:
>>On Sep 16, 11:51 am, raph...@gmail.com wrote:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly.
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.

Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.
"This kind of task" was an artificial bit of code specifically
written to experiment with manipulating pointers. An investigative
doodle, nothing more.

Personally, I'm not as ready as vippstar is to give you the
award; we're only halfway through the month. But I'd be surprised
if you weren't on the ballot a couple weeks from now. Have you
chosen your running mate yet?

--
Er*********@sun.com

Sep 16 '08 #20
On Sep 16, 12:51*pm, Eric Sosman <Er*********@sun.comwrote:
s0****@gmail.com wrote:
On Sep 16, 12:06 pm, vi******@gmail.com wrote:
On Sep 16, 7:59 pm, s0s...@gmail.com wrote:
>On Sep 16, 11:51 am, raph...@gmail.com wrote:
On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly.
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.

* * *"This kind of task" was an artificial bit of code specifically
written to experiment with manipulating pointers. *An investigative
doodle, nothing more.
No. This "investigate doodle" demonstrated this kind of task. But this
kind of task is also common in real-world programs, and it's
important. I, for one, have actually done this, without realizing I
was using an extension.
* * *Personally, I'm not as ready as vippstar is to give you the
award; we're only halfway through the month. *But I'd be surprised
if you weren't on the ballot a couple weeks from now. *Have you
chosen your running mate yet?
I did not understand a word of that paragraph.

Sebastian

Sep 16 '08 #21
sh******@gmail.com writes:
On Sep 16, 9:46*pm, Keith Thompson <ks...@mib.orgwrote:
>sh.vi...@gmail.com writes:
On Sep 16, 8:15*pm, raph...@gmail.com wrote:
Is this valid?

*In my opinion this
extension is a bad idea; it can be convenient, but it doesn't give you
anything you can't do by other means, it has some bizarre
consequences,

I think Bus Error,on some machines, is one of those consequences.
Not really. Or rather, any misuse of arithmetic on void* that might
give you a bus error would almost certainly do the same thing if you
use the standard C equivalent (converting to and from character
pointers).

[...]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #22
Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
[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.

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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #23
Richard wrote:
ja*********@verizon.net writes:
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:
implementation-specific meaning on your machine is (probably) only
that p and q point at locations 4 bytes apart; that doesn't say
anything about how much has been added to q to get the current value
of p.
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.
Sep 16 '08 #24
On Sep 16, 1:47*pm, Keith Thompson <ks***@mib.orgwrote:
Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
[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?

Sebastian

Sep 16 '08 #25
Keith Thompson <ks***@mib.orgwrites:
Richard<rg****@gmail.comwrites:
>Keith Thompson <ks***@mib.orgwrites:
[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.
>
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.
--
Sep 16 '08 #26
ja*********@verizon.net writes:
Richard wrote:
>ja*********@verizon.net writes:
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".
>
implementation-specific meaning on your machine is (probably) only
that p and q point at locations 4 bytes apart; that doesn't say
anything about how much has been added to q to get the current value
of p.

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
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
>The first printf gives me:

3214862936

And the second:

3214862940
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

Sep 16 '08 #27
s0****@gmail.com writes:
On Sep 16, 1:47*pm, Keith Thompson <ks***@mib.orgwrote:
>Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
[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
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #28


Richard wrote:
Keith Thompson <ks***@mib.orgwrites:
Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
[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.

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.

--
Sep 16 '08 #29
Richard wrote:
ja*********@verizon.net writes:
Richard wrote:
ja*********@verizon.net writes:
....
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".
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
The first printf gives me:

3214862936

And the second:

3214862940
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.
Sep 16 '08 #30
Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
>Richard<rg****@gmail.comwrites:
>>Keith Thompson <ks***@mib.orgwrites:
[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.
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.
>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.
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).
>Pointer arithmetic doesn't mean what you think it means.
As you continue to demonstrate.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #31
s0****@gmail.com wrote:
On Sep 16, 12:51 pm, Eric Sosman <Er*********@sun.comwrote:
>s0****@gmail.com wrote:
>>On Sep 16, 12:06 pm, vi******@gmail.com wrote:
On Sep 16, 7:59 pm, s0s...@gmail.com wrote:
On Sep 16, 11:51 am, raph...@gmail.com wrote:
>On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
>>b = ((unsigned char *)b) + 5 * sizeof *a;
>I see, got to switch to char * so that it can be incremented properly.
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.
"This kind of task" was an artificial bit of code specifically
written to experiment with manipulating pointers. An investigative
doodle, nothing more.

No. This "investigate doodle" demonstrated this kind of task. But this
kind of task is also common in real-world programs, and it's
important. I, for one, have actually done this, without realizing I
was using an extension.
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.
> Personally, I'm not as ready as vippstar is to give you the
award; we're only halfway through the month. But I'd be surprised
if you weren't on the ballot a couple weeks from now. Have you
chosen your running mate yet?
I did not understand a word of that paragraph.
So you understand English as well as you understand C?

--
Er*********@sun.com
Sep 16 '08 #32
jameskuy...@verizon.net 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
Sep 16 '08 #33
Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
>Richard<rg****@gmail.comwrites:
>>Keith Thompson <ks***@mib.orgwrites:
[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.
x86 "real mode"? far pointer are usually printed as seg:offset 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[i]);
}
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?
>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.
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,

--
Jean-Marc
Sep 16 '08 #34
On Sep 16, 11:07 pm, Jean-Marc Bourguet <j...@bourguet.orgwrote:
<snip>
@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[i]);
}
return 0;}
I'm curious, why don't you cast &t[i] to (void *)?
My thoughts: &t[i] 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)

Sep 16 '08 #35
On Sep 16, 2:52*pm, Eric Sosman <Er*********@sun.comwrote:
s0****@gmail.com wrote:
>On Sep 16, 12:51 pm, Eric Sosman <Er*********@sun.comwrote:
>>s0****@gmail.com wrote:
On Sep 16, 12:06 pm, vi******@gmail.com wrote:
On Sep 16, 7:59 pm, s0s...@gmail.com wrote:
>On Sep 16, 11:51 am, raph...@gmail.com wrote:
>>On Sep 16, 4:20 pm, vipps...@gmail.com wrote:
>>>b = ((unsigned char *)b) + 5 * sizeof *a;
>>I see, got to switch to char * so that it can be incremented properly.
>No, to unsigned char *. But if your compiler can do it with the void
>*, then do it with the void *. It's probably specialized for that kind
>of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.
* * *"This kind of task" was an artificial bit of code specifically
written to experiment with manipulating pointers. *An investigative
doodle, nothing more.
>No. This "investigate doodle" demonstrated this kind of task. But this
kind of task is also common in real-world programs, and it's
important. I, for one, have actually done this, without realizing I
was using an extension.

* * *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).
>>* * *Personally, I'm not as ready as vippstar is to give you the
award; we're only halfway through the month. *But I'd be surprised
if you weren't on the ballot a couple weeks from now. *Have you
chosen your running mate yet?
>I did not understand a word of that paragraph.

* * *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

Sep 16 '08 #36
In article <ga**********@registered.motzarella.org>,
Richard <rg****@gmail.comwrote:
....
>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...

Sep 16 '08 #37
Richard<rg****@gmail.comwrites:
[...]
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
>>The first printf gives me:

3214862936

And the second:

3214862940
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #38
Keith Thompson <ks***@mib.orgwrites:
s0****@gmail.com writes:
>On Sep 16, 1:47Â*pm, Keith Thompson <ks***@mib.orgwrote:
>>Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:
[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....
Sep 16 '08 #39
ga*****@shell.xmission.com (Kenny McCormack) writes:
In article <ga**********@registered.motzarella.org>,
Richard <rg****@gmail.comwrote:
...
>>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...
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.
Sep 16 '08 #40
s0****@gmail.com wrote:
Eric Sosman <Er*********@sun.comwrote:
.... snip ...
>
>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).
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>

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 16 '08 #41
ja*********@verizon.net wrote:
Richard wrote:
>Keith Thompson <ks***@mib.orgwrites:
>>Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:

[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.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 16 '08 #42
CBFalconer <cb********@yahoo.comwrites:
s0****@gmail.com wrote:
>Eric Sosman <Er*********@sun.comwrote:
... snip ...
>>
>>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).

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.
>
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>
--
Sep 16 '08 #43
sh******@gmail.com wrote:
>
.... snip ...
>
I think Bus Error,on some machines, is one of those consequences.
Thanks all for gcc info. I thought gcc didn't take anything as
stride value for void pointers
Its a non-standard extension. Use of -ansi -pedantic will shut it
off, and make gcc a standard conforming compiler. Advisable to add
-W -Wall.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Sep 16 '08 #44
CBFalconer <cb********@yahoo.comwrites:
ja*********@verizon.net wrote:
>Richard wrote:
>>Keith Thompson <ks***@mib.orgwrites:
Richard<rg****@gmail.comwrites:
Keith Thompson <ks***@mib.orgwrites:

[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.
It sure is. Why do you do it?
>
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
But you cant name one that does that.
will contain the information about school, grade, small boy, and
which piece of paper. malloc allocates storage, not necessarily
conventional memory.
Malloc allocates storage. It returns a pointer. To memory. Withing the
bounds of virtual memory.

No wonder half of you have never managed to teach anyone what pointers
are if you constantly try to make it more complicated than it is.
Sep 16 '08 #45
On 16 Sep 2008 at 21:48, Richard wrote:
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.
It's another clc obsession, though. void* and char* can be losslessly
converted back and forth. Nonetheless, /in theory/ they can have
different representations. The fact that they don't on any system in
existence or any system that will ever be built doesn't stop the "regs"
waking up in a cold sweat worrying about it.

It would merely be tragic if they didn't go to such lengths to confuse C
newbies with this and other idiotic angels-on-the-head-of-a-pin debates.

Sep 16 '08 #46
On 16 Sep 2008 at 21:49, CBFalconer wrote:
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.
Is it possible that your memory of MS-DOS has become fuzzied over time?
I mean, I know it was a primitive OS, but really...

Sep 16 '08 #47
On 16 Sep 2008 at 17:30, Keith Thompson wrote:
If x isn't initialized, referring to its value invokes undefined
behavior. It's possible, on some systems, that x could have a value
such that attempting to read it causes a program crash. (Before you
ask, no, I don't have an example.)
Well, what a surprise!

Just as long as you don't let that horrible, messy thing called reality
get in the way of the simple purity of the Abstract ISO C Machine.

Sep 16 '08 #48
Antoninus Twink <no****@nospam.invalidwrites:
[...]
void* and char* can be losslessly
converted back and forth. Nonetheless, /in theory/ they can have
different representations.
[...]

Wrong.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #49
Keith Thompson <ks...@mib.orgwrote:
... why does printf have a "%p" format?
That's actually a very good question! If you ever hear
a good answer, please share it.

--
Peter
Sep 16 '08 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: kazack | last post by:
I am under the the impression that a variable is what is stored in a memory address and a pointer is the memory address of the variable? I was looking to use a function that does not return a...
18
by: steve | last post by:
I'm trying to create a structure of three pointers to doubles. For which I have: typedef struct { double *lst_t, *lst_vc, *lst_ic; } last_values; I then need to allocate space for...
14
by: streamkid | last post by:
i'm a learning newbie at c++... and i have the following question... reading some source code, i saw this: int function(const void * one, const void * two) { int var1, var2; var1 =...
21
by: Bo Yang | last post by:
As long as I write c++ code, I am worry about the pointer. The more the system is, the dangerous the pointer is I think. I must pass pointers erverywhere, and is there a way to ensure that every...
4
by: Jeffrey Spoon | last post by:
Hello, I am trying to make a simple function that returns a pointer to another function. In my header file I've declared my function pointer: void (*pStateFunction) (void); //assume the function...
10
by: Zero | last post by:
Hello all, I wonder about void? To which category in the C programming language does it belong? Of how many bits consits void? Is it possible to define a varibale called void a;
21
by: Chad | last post by:
At the following url http://c-faq.com/lib/qsort2.html, they have the following Q: Now I'm trying to sort an array of structures with qsort. My comparison function takes pointers to structures,...
17
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the...
18
by: mdh | last post by:
May I ask the following. By K&R's own admission, the example used to describe function pointers is complex ( on P119). In addition, the use of casts has been stated by some on this group as...
28
by: junky_fellow | last post by:
Guys, Consider a function func(void **var) { /* In function I need to typecast the variable var as (int **) I mean to say, I need to access var as (int **) }
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.