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?
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)
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
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.
> 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
> 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:
And the second:
Now, that is 4. On my machine.
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"
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 );
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
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
> 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
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.
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,
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;
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
> Richard<rgr...@gmail.com> writes:
>> vipp...@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.
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.
> Richard wrote:
>> vipp...@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,
--
"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?
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
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).
[...]
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.
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.
Then how come C99 introduces the intptr_t typedef and the PRIdPTR
conversion specifier to print it as decimal?
Sebastian
> Richard<rgr...@gmail.com> writes:
>> Keith Thompson <ks...@mib.org> writes:
> [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.
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
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.
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.
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.
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?
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
> Keith Thompson <ks...@mib.org> writes:
>
>> Richard<rgr...@gmail.com> writes:
>>> Keith Thompson <ks...@mib.org> writes:
>> [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
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)
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
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...
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.
> s0s...@gmail.com writes:
>> On Sep 16, 1:47 pm, Keith Thompson <ks...@mib.org> wrote:
>>> Richard<rgr...@gmail.com> writes:
>>> > Keith Thompson <ks...@mib.org> writes:
>>> [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....
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.
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.
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.
> s0s...@gmail.com wrote:
>> Eric Sosman <Eric....@sun.com> wrote:
>>
> ... 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.
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.
> james...@verizon.net wrote:
>> Richard wrote:
>>> Keith Thompson <ks...@mib.org> writes:
>>>> Richard<rgr...@gmail.com> writes:
>>>>> Keith Thompson <ks...@mib.org> writes:
>>>>
>>>> [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.
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.
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...
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.
Wrong.
That's actually a very good question! If you ever hear
a good answer, please share it.
--
Peter
> Antoninus Twink <nos...@nospam.invalid> writes:
> [...]
>> void* and char* can be losslessly
>> converted back and forth. Nonetheless, /in theory/ they can have
>> different representations.
> [...]
>
> Wrong.
Well, obviously. Look at the source.
Nevertheless, incredible as it may seem, some people might not realise even
now that the source is unreliable, so here's C&V from both Standards (the
wording is identical in each):
C89, 3.1.2.5, and C99, 6.2.5(26): "A pointer to void shall have the same
representation and alignment requirements as a pointer to a character
type."
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Implementations have considerable licence over the textual representation
of pointer values. One MS-DOS compiler I have used (dim and distant past,
admittedly) would print pointer values like this: DS:FADE
I mean *obviously* that's a number, right? It's just not immediately
obvious /which/ number it is.
Well, how about "to allow printf to output a printable char
representation of a void* pointer, readable by scanf to
reconstitute that pointer".
Well, great.
CBF says something is a problem in practise. I point out that it's at
worst a problem in theory. And actually it isn't even that.
It seems that the ISO C committee have a bit more common sense than the
average clc regular in these matters.
I'm not sure of the basis for your question. Do you mean to imply
that "%p" isn't useful? If so, are you suggesting the use of other
existing formats, or questioning the need to print pointer values in
the first place?
Another interesting question is why there's no format for printing
function pointers; I suspect the answer is that it wasn't thought to
be sufficiently useful. On many systems, casting to void* and using
"%p" works; more generally, you can always get at the representation
as an array of unsigned char and print it in, say, hexadecimal.
> vipp...@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.
This thread has gone off in another direction, but I want to come back
to this. Please, coders of the world, don't take this remark from
Richard to heart -- think of your children!
We are currently living though an particularly stable few decades in
terms of machine architecture, but it was not always so and may not
always be so in the future. A large body of C code that plays fast
and loose with indeterminate pointers, treating pointers as if they
were numbers into a flat value space, or assumes that casts (on
pointers) don't change values will condemn future generations to one
of two fates:
(a) All CPU's look more and more alike and none do anything clever
with the address space because that valuable body of code won't work
without massive porting effort; or
(b) A future generation of rookies (they may be your kids!) has to
wade through all that 25 year old code looking for these bugs.
The serious point is that is does not matter if there are no machines
*now* that trap on the above code or code like
int a[1], *ap = a; a--;
there were such machine once and I, for one, would like to think there
might be again. At the very least, are you /sure/ you know exactly
which undefined behaviours will still work in 25 years time?
[Aside: Do your own thought experiment -- mine goes like this: 25
years ago I worked for a large computer company in a office with no
network. They wanted me to implement a protocol whose name I now
forget because they did not think this TCP/IP stuff would take off. I
was sent off to see a competitor that had just stared to export to the
UK to see if their 68000-based systems were any good (the then tiny
Sun Microsystems). I did not see an Ethernet until the next year --
it was a fat yellow cable that could not take tight bends but it did
run at 1M bit and you could get an interface card for only £500.
There were no laptops and PCs were a joke. Graphical interfaces were
just breaking out the research lab.]
--
Ben.
> Richard<rgr...@gmail.com> writes:
>
>> vipp...@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.
>
> This thread has gone off in another direction, but I want to come back
> to this. Please, coders of the world, don't take this remark from
> Richard to heart -- think of your children!
Oh for goodness sake Ben, I was not condoning it! But to say "it will
not increment" is clearly false.
How often is this useful? When it is, how useful is %p?
> readable by scanf to reconstitute that pointer".
Having printed a pointer with %p, how does a program guarantee
that subsequent printed characters will not undermine scanf's
ability to reconstitute a comprable pointer value?
If I do something like...
printf("ptr is %p\n", (void *) ptr);
...what is the guarantee that the output won't exceed an
implementation's limit on text line width?
When I do print pointers, I hex dump the representation.
It's the only way to gain full control over the output.
#include <stdio.h>
#include <limits.h>
#define CHAR_NIBBLE ((CHAR_BIT + 3) / 4)
void dump_ptr(FILE *fp, const void *ptr)
{
const unsigned char *p = (const unsigned char *) &ptr;
size_t i;
for (i = 0; i < sizeof ptr; i++)
fprintf(fp, "%0*X", CHAR_NIBBLE, (unsigned) *p++);
}
--
Peter
That's the problem.
> One MS-DOS compiler I have used (dim and distant past,
> admittedly) would print pointer values like this: DS:FADE
> I mean *obviously* that's a number, right? It's just not
> immediately obvious /which/ number it is.
In the rare cases where I print pointers, I'm less concerned
about the pointer value itself than I am about how the value
is displayed.
Realising this, I've often asked myself why I bothered
printing the pointer in the first place! Which brings us
back to the question of why %p exists. [And why, if it is
to exist, is there no corresponding specifier for function
pointers.]
--
Peter
Okay, terminology: That's not a task, it's a tactic.
A task is, for example, to make an interest calculation and
round the (probably irrational) result to hundredths of a
dollar. Various tactics might be employed to accomplish such
a task: Absalom might use log() and exp(), Bertram might use
pow(), Cecil might round by adding 0.005, scaling, truncating,
and re-scaling, Dudley might round by means of a precalculated
logarithmic table. Getting a pointer to the umpteenth element
of an array might be a task, accomplishing it via arithmetic
on a void* (forbidden in C) or a char* (signedness your option)
or a type-of-array-element* would be a means to that end, but
not an end in itself.
>>>> 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."
It means: (1) vippstar awarded you the "worst advice of the
month" award, (2) I said the award would be premature because
the month is only half over and worse advice might conceivably
yet appear, but (3) I thought your advice would certainly be
among the contenders for worst. I also (4) made a reference to
current events in USA politics, the suggestion being that your
maundering about "perhaps the OP doesn't need portability" reminds
one of a politician desperately backtracking. Your "Besides, void*
seems more natural" has all the sincerity of Pooh-Bah's "I wasn't
there."
--
Eric Sosman
eso...@ieee-dot-org.invalid
Why? I honestly can't see why you think it must do anything at all.
The whole point of my post was to say "beware" to people who
mock undefined behaviour because you don't know the future. On the
Cambridge CAP machine, that code would terminate the program before
the increment. In fact, 'int *x; x;' could terminate the program if the
compiler did not optimise the reference to x away. Do you know that
the code will increment on every future machine, now that this awkward
old one is so much scrap?
--
Ben.
This originated with an attempt by one of the trolls to refute a
statement that CBFalconer never actually made, in contrast to the
perfectly correct statement that he did make.
The language requires void* and char* to have the same
representation, but it does not allow pointer arithmetic on void*
(Chuck made the latter statement). More precisely, any attempt
to perform such arithmetic is a constraint violation, requiring
a diagnostic.
The whole point of having void* in the language is that it
doesn't point to any specific type. Allowing arithmetic on
void* as an extension, as if it pointed to a one-byte object,
weakens that distinction for the sake of some minor convenience.
(A side effect of the way this extension is implemented is that,
absurdly, sizeof(void)==1.)
> Richard<rgr...@gmail.com> writes:
>
>> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>
>>> Richard<rgr...@gmail.com> writes:
>>>
>>>> vipp...@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.
>>>
>>> This thread has gone off in another direction, but I want to come back
>>> to this. Please, coders of the world, don't take this remark from
>>> Richard to heart -- think of your children!
>>
>> Oh for goodness sake Ben, I was not condoning it! But to say "it will
>> not increment" is clearly false.
>
> Why? I honestly can't see why you think it must do anything at all.
I dont think it *must* do anything at all. But I am yet to see a machine
where it is not incremented if it is not initialised. Its
"uninitialised" value is incremented in each and every case. Sure its
"undefined behaviour in terms of the value, but its still UDV+1 ...
>
> The whole point of my post was to say "beware" to people who
> mock undefined behaviour because you don't know the future. On the
Let me make something very clear - I am not mocking UDB. I am just
pointing out that in most cases it is WRONG to say the unitialised
variable is NOT incremented. It is. In nearly all cases and certainly in
EVERY case I have worked on on various common machines.
There's two things wrong with what you said:
1 It doesn't matter whether the cast is to
(char *) or (unsigned char *),
because the pointer arithmetic is the same.
2 (void *) is wrong. You shouldn't write code that only works
on your compiler, without a special reason.
There is no special reason here.
--
pete
And who exactly said "it will not increment"?
vippstar's actual statement, which you quoted, was:
"... assuming x was initialized, it would be incremented by 1".
He quite reasonably chose not to make any claim about what would
happen if x was not initialized.
> Richard<rgr...@gmail.com> writes:
>> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>> Richard<rgr...@gmail.com> writes:
>>>> vipp...@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.
>>>
>>> This thread has gone off in another direction, but I want to come back
>>> to this. Please, coders of the world, don't take this remark from
>>> Richard to heart -- think of your children!
>>
>> Oh for goodness sake Ben, I was not condoning it! But to say "it will
>> not increment" is clearly false.
>
> And who exactly said "it will not increment"?
>
> vippstar's actual statement, which you quoted, was:
>
> "... assuming x was initialized, it would be incremented by 1".
>
> He quite reasonably chose not to make any claim about what would
> happen if x was not initialized.
Can you be more obstinate and childish? There is nothing "reasonable"
about it all in the context of which I am talking. In the greater
majority of cases x will incremented REGARDLESS of whether it was
initialised or not. Why this is so tricky for you to understand I am not
sure. You seem unable to think outside of the standard. Do try.
Yes, yes demons out of noses etc etc. But meanwhile in the real world.
And ONCE AGAIN : yes I DO understand that incrementing an uninitialised
variable is a silly thing to do.
> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>
>> Richard<rgr...@gmail.com> writes:
>>
>>> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>>
>>>> Richard<rgr...@gmail.com> writes:
>>>>
>>>>> vipp...@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.
>>>>
>>>> This thread has gone off in another direction, but I want to come back
>>>> to this. Please, coders of the world, don't take this remark from
>>>> Richard to heart -- think of your children!
>>>
>>> Oh for goodness sake Ben, I was not condoning it! But to say "it will
>>> not increment" is clearly false.
>>
>> Why? I honestly can't see why you think it must do anything at all.
>
> I dont think it *must* do anything at all.
Good. We are agreed. I can't see how your "even if it wasn't
initialised it would be incremented by something" is consistent with
that because it suggests at least one thing must happen -- some form
of increment -- but it seems you don't hold that view any more.
> But I am yet to see a machine
> where it is not incremented if it is not initialised. Its
> "uninitialised" value is incremented in each and every case. Sure its
> "undefined behaviour in terms of the value, but its still UDV+1 ...
Ah, you do it seems. That is not what the standard says. It says
that the value may be a trap representation and that accessing such a
thing in the normal way is undefined. At that point (which can be
before the increment) the program may terminate or do whatever your
favourite example of UB is. I think termination is undefined enough
and is what the machine I described would do.
>> The whole point of my post was to say "beware" to people who
>> mock undefined behaviour because you don't know the future. On the
>
> Let me make something very clear - I am not mocking UDB. I am just
> pointing out that in most cases it is WRONG to say the unitialised
> variable is NOT incremented.
I did not say it is *not* incremented -- you said it *will* be and at
the time you gave no exceptions.
The standard says it may not be and think you have missed that
possibility. Pointers can be invalid in such a way that merely
"touching" them cause a fault. This is an excellent bit of standards
writing and allows C to be implemented on machines with very strict
address checking in hardware (such as the CAP).
> It is. In nearly all cases and certainly in
> EVERY case I have worked on on various common machines.
I would never have posted if you had said "even uninitialised, it will
usually be incremented". You agree the undefined behaviour is
important but rather than point out that the example has undefined
behaviour you just chose to say what usually happens on current
machines. That does not add to the general readers stock of
understanding.
--
Ben.
Printing pointer values probably useful very often, but I like having
"%p" for those cases where it is useful.
>> readable by scanf to reconstitute that pointer".
>
> Having printed a pointer with %p, how does a program guarantee
> that subsequent printed characters will not undermine scanf's
> ability to reconstitute a comprable pointer value?
I must admit I've used *printf and *scanf to print and reconstitute a
pointer value. But with reasonable precautions, such as printing the
value at the end of a line with something recognizable in front of it,
I wouldn't have any qualms about assuming that the output format will
be reasonable. A new-line character in the middle of the result would
mess this up, but I'm content to count on vendors not to do something
that silly.
> If I do something like...
>
> printf("ptr is %p\n", (void *) ptr);
>
> ...what is the guarantee that the output won't exceed an
> implementation's limit on text line width?
There's no actual guarantee of this, but again, I'm willing to assume
reasonable behavior. Having the output of "%p" exceed the maximum
text line length is hardly the only silly but legal thing a perverse
implementation could do.
> When I do print pointers, I hex dump the representation.
> It's the only way to gain full control over the output.
>
> #include <stdio.h>
> #include <limits.h>
>
> #define CHAR_NIBBLE ((CHAR_BIT + 3) / 4)
>
> void dump_ptr(FILE *fp, const void *ptr)
> {
> const unsigned char *p = (const unsigned char *) &ptr;
> size_t i;
> for (i = 0; i < sizeof ptr; i++)
> fprintf(fp, "%0*X", CHAR_NIBBLE, (unsigned) *p++);
> }
Sure, that works too. On the other hand, on some systems it's
traditional to show addresses in octal rather than in hexadecimal; on
others, address might be segmented, and your method loses the
distinction between the discrete pieces of the address, something that
"%p" would probably capture.
And it prints the bytes backwards on a little-endian system.
Also, if two different representations represent the same address
(possible in a segmented addressing system), "%p" could at least
potentially normalize them.
You know what? This most recent statement of yours:
In the greater majority of cases x will incremented REGARDLESS of
whether it was initialised or not.
is one that I agree with.
So what's your problem?
Read the quoted material above. vippstar made a perfectly correct
statement, that x will be incremented if it's been initialized
(leaving aside for the moment the question of whether it's incremented
by 1 or by 4). Expanding that statement to cover the case where x has
not been initialized would have required, for accuracy, a discussion
of undefined behavior, trap representations, and all that stuff. He
quite reasonably chose not to open that can of worms.
You responded by claiming, without qualification, that x will be
incremented even it hasn't been initialized. You've now backed off
from that statement with your "greater majority of cases"
qualification, but you refuse to acknowledge that your more recent
statement differs from your earlier one.
> Yes, yes demons out of noses etc etc. But meanwhile in the real world.
>
>
> And ONCE AGAIN : yes I DO understand that incrementing an uninitialised
> variable is a silly thing to do.
I'm glad to hear it -- and a bit surprised, given that many of your
earlier statements in this thread did not demonstrate such knowledge.
Please try to understand that your earlier claim that:
Even if it wasnt initialised it would be incremented by something.
could easily mislead an unwary newbie into thinking that it's safe to
increment an uninitialized pointer.
In addition, your later statement:
Oh for goodness sake Ben, I was not condoning it! But to say "it will
not increment" is clearly false.
is correct, but it could lead someone to the incorrect conclusion that
someone had actually written "it will not increment".
You might think that putting words into other people's mouths makes it
easy to win arguments, but that trick doesn't work so well when
people's actual words are recorded.
>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.
If you cast b to int* then the expression could be simpler:
b = ((int *)b) + 5;
Any pointer to a complete type can be used for pointer arithmetic.
>
>> 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 );
Why don't you just run it through your compiler and note the mandatory
diagnostic? The left operand of -> must be a pointer to struct. While
b has the correct value, does it have the correct type?
--
Remove del for email
> On Sep 16, 11:07 pm, Jean-Marc Bourguet <j...@bourguet.org> wrote:
> <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 *)?
I just forgot it as I normally don't make a difference between char* and
other pointers and always cast when passing them to variadic functions (see
for y above). But, while I haven't the time to back up my opinion with
citations, I also think that it shouldn't make a difference for that
reason:
> 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)
I think so.
Yours,
--
Jean-Marc
> Another interesting question is why there's no format for printing
> function pointers
I would assume that, due to the existence of dynamic loading and
relocatable libraries, you can't realistically enforce that the
printable representation of a function pointer, when fed to scanf,
reconstitutes that function pointer.
Sure, it can be *done*, but making every implementation do it is
pretty far out of line.
-o
I don't think that's the issue. Pointer values are only expected to
be valid within the current execution of the current program. Within
that context, you can already save the representation of a function
pointer (say, by treating it as an array of unsigned char and getting
a hexadecimal representation) and then later reconstitute the pointer
value, and it will work. A printf format for function pointers
wouldn't create any new problems.
I think it's just a matter of insufficient demand.
> >>>>>>>> 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.
nonsense
> >>>>> You can have the "worst advice of the month" clc award.
note this
> >>>>> 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).
there is a *well defined* and *portable* way to do this. So why choose
a non-portable way? I'm sorry I've had this sort of argument before
(in my work place) we really are on different planets. Why NOT
use a portable means, if it exists?
> >>>> Besides, void * seems more natural for this kind
> >>>> of task.
rubbish
> >>> "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.
so now you know- so don't do it again
> > 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.
thats the ""worst advice of the month" clc award" referredf to
earlier. He probably thinks somone will come up with something
even more stupid before the end of the month
> >>> But I'd be surprised
> >>> if you weren't on the ballot a couple weeks from now.
but he still thinks it's pretty stupid
> >>> Have you
> >>> chosen your running mate yet?
the americans are having an election. It involves a process
called "choosing a running mate". He was making a half-humerous
reference to this.
Note: comp.lang .c doesn't have a "worst advice of the month award"
(perhaps it should)
> >> I did not understand a word of that paragraph.
I hope I helped you there
> > 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.
que?
> 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."
--
Nick Keighley
"an easy to use computer should do what I mean, not what I say,
and by no means send me a dancing paper clip to ask"
Nicholas Negroponte (MIT Professor)
> >>> >> 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....- Hide quoted text -
but in general they aren't. Think DOS. Think IBM mainframe.
Are you trying to be dense?
--
Nick Keighley
> > > > ... why does printf have a "%p" format?
>
> > > That's actually a very good question! If you ever hear
> > > a good answer, please share it.
to print pointer representations...
> > Implementations have considerable licence over the textual
> > representation of pointer values.
>
> That's the problem.
>
> > One MS-DOS compiler I have used (dim and distant past,
> > admittedly) would print pointer values like this: DS:FADE
> > I mean *obviously* that's a number, right? It's just not
> > immediately obvious /which/ number it is.
>
> In the rare cases where I print pointers, I'm less concerned
> about the pointer value itself than I am about how the value
> is displayed.
>
> Realising this, I've often asked myself why I bothered
> printing the pointer in the first place! Which brings us
> back to the question of why %p exists. [And why, if it is
> to exist, is there no corresponding specifier for function
> pointers.]
I've used it to identify objects. The one thing that is unique
is the address!! For instance to track memory leaks. A log
kept track of when things were allocated and freed (and some
other history). You then had a fighting chance of working
out why things were not freed. Note this would work whatever
representation %p used.
--
Nick Keighley
"Morality is a spandrel of the game theoretic implications of the
society of symbol users.
We impute moral worth to the non-social world on that basis."
(John Wilkins talk.origins)
> Richard<rgr...@gmail.com> writes:
>
>> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>
>>> Richard<rgr...@gmail.com> writes:
>>>
>>>> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>>>>
>>>>> Richard<rgr...@gmail.com> writes:
>>>>>
>>>>>> vipp...@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.
>>>>>
>>>>> This thread has gone off in another direction, but I want to come back
>>>>> to this. Please, coders of the world, don't take this remark from
>>>>> Richard to heart -- think of your children!
>>>>
>>>> Oh for goodness sake Ben, I was not condoning it! But to say "it will
>>>> not increment" is clearly false.
>>>
>>> Why? I honestly can't see why you think it must do anything at all.
>>
>> I dont think it *must* do anything at all.
>
> Good. We are agreed. I can't see how your "even if it wasn't
> initialised it would be incremented by something" is consistent with
> that because it suggests at least one thing must happen -- some form
> of increment -- but it seems you don't hold that view any more.
Hold on here. You're trying to be smart. Once again
1) I do not think that incrementing a non initialised var is a good
idea.
2) Yes I know the standard says "UDB".
3) In ALL cases I have ever known it IS incremented.
So to say "it is not incremented" is not true.
We can play all the word games you like. But the above are true.
>
>> But I am yet to see a machine
>> where it is not incremented if it is not initialised. Its
>> "uninitialised" value is incremented in each and every case. Sure its
>> "undefined behaviour in terms of the value, but its still UDV+1 ...
>
> Ah, you do it seems. That is not what the standard says. It says
Do you have a comprehension issue today? I am not supporting that
increment. I am not saying one should do it. I am not arguing about what
the standard says, I am merely saying that in the real world in the
great majority of cases it is indeed incremented.
Which part of the above confuses you or you trying to manipulate this
into making me look like some clueless nOOb who is not aware of the
dangers of toying with UDB?
Are you?
What pointer do you know that doesnt render as a number? MSDOS,
anything. I have built various SW systems on various machines and am yet
to see a pointer which did not correspond to a memory address. And lets
face it that address IS a number whether you like to be too clever about
it or not.
--
<snip>
> What pointer do you know that doesnt render as a number? MSDOS,
> anything. I have built various SW systems on various machines and am yet
> to see a pointer which did not correspond to a memory address. And lets
> face it that address IS a number whether you like to be too clever about
> it or not.
You are wrong. Pointers are objects. Objects have a representation,
which is a bit string.
Bit strings can interpreted in arbitrary ways. One of them is treating
the bit string as a base 2 integer.
I'm sure you'll come up again with something stupid to say. Don't let
me down.
You're missing the point, void * and char * are guaranteed to have the
same representation, I haven't seen anyone else say otherwise, and the
accepted solution involves converting back and forth through
(unsigned) char *. The problem is that since the Standard expressly
forbids pointer arithmetic on void * pointers (despite similarities
with char pointers, they are a different type), many compilers do not
support it and those that do cannot support it in full compliance
mode. The objection stems from the issue of portability, especially
given that there is a simple, portable alternative.
--
Robert Gamble
[snip incrementing void pointers]
> > 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.
>
> You're missing the point, void * and char * are guaranteed to have the
> same representation, I haven't seen anyone else say otherwise, and the
> accepted solution involves converting back and forth through
> (unsigned) char *. The problem is that since the Standard expressly
> forbids pointer arithmetic on void * pointers (despite similarities
> with char pointers, they are a different type), many compilers do not
> support it and those that do cannot support it in full compliance
> mode. The objection stems from the issue of portability, especially
> given that there is a simple, portable alternative.
Well, that is not entirely true. It's possible for a compiler to
support [*] incrementing void * pointers in strict conformance mode.
Incrementing a void pointer is a constraint violation which, as far as
the standard is concerned, requires a diagnostic.
The compiler may, along with emitting that diagnostic, choose to
increment the pointer as if it were a char * pointer.
[*] support as in, choose a particular behavior when undefined
behavior is invoked.
> What pointer do you know that doesnt render as a number? MSDOS,
> anything. I have built various SW systems on various machines and am yet
> to see a pointer which did not correspond to a memory address.
Clearly a pointer has to "correspond" with a "memory address" in some
way, otherwise you couldn't use it to access memory.
> And lets face it that address IS a number whether you like to be
> too clever about it or not.
/Part of/ an address has to respect arithmetic, at least + - = < >.
That doesn't mean the address /is/ a number. One only has to remember
segmented addresses to realise that.
--
'It changed the future .. and it changed us.' /Babylon 5/
Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN
No, but I can see there no point in continuing. We have both made our
positions clear.
--
Ben.
How is that relevant? You clearly do not know ALL cases, since there are
real machines (one has already been cited) where it is NOT incremented.
The existence of that machine (and many others with similar properties)
is far more relevant than your lack of experience with such machines.
> So to say "it is not incremented" is not true.
No one but you has said anything like that, and you have said it only to
refute the claim (which no one made). What has been said is that your
claim that it is incremented is not always true.
...
> the standard says, I am merely saying that in the real world in the
> great majority of cases it is indeed incremented.
And if you had qualified your original statement with "in the great
majority of cases", it would have been unobjectionable. It was your flat
out, unqualified assertion that it is incremented that people have been
objecting to.
> Which part of the above confuses you or you trying to manipulate this
> into making me look like some clueless nOOb who is not aware of the
> dangers of toying with UDB?
You don't look like a clueless nOOb. A nOOb has too little experience,
and is generally very aware of that fact. You look like someone who has
too much experience with a limited class of machines, and as a result
tends to assume that all machines are like the ones you have experience
with, or at least all machines worth bothering to think about.
Actually,no, you haven't. You keep trying to put words in my mouth. I am
surprised. My comments are clear enough.
> Richard wrote:
>
>> What pointer do you know that doesnt render as a number? MSDOS,
>> anything. I have built various SW systems on various machines and am yet
>> to see a pointer which did not correspond to a memory address.
>
> Clearly a pointer has to "correspond" with a "memory address" in some
> way, otherwise you couldn't use it to access memory.
>
>> And lets face it that address IS a number whether you like to be
>> too clever about it or not.
>
> /Part of/ an address has to respect arithmetic, at least + - = < >.
> That doesn't mean the address /is/ a number. One only has to remember
> segmented addresses to realise that.
So, you are saying that in segmented architectures (which I wrote
assembler VGA libraries for) your debugger does not store the pointer
parts in binary registers which in turn render as numbers on the
debugger display?
Now this is getting silly.
My only comment was that in most cases an uninitialised pointer will
indeed increment in the real world.
nothing more. Nothing less.
Quite why this has turned into a crusade for clc standard correctness is
any ones guess.
> On Sep 17, 3:05 pm, Richard <rgr...@gmail.com> wrote:
>
> <snip>
>
>> What pointer do you know that doesnt render as a number? MSDOS,
>> anything. I have built various SW systems on various machines and am yet
>> to see a pointer which did not correspond to a memory address. And lets
>> face it that address IS a number whether you like to be too clever about
>> it or not.
>
> You are wrong. Pointers are objects. Objects have a representation,
No. I am not wrong. Did you not see "render" there?
> which is a bit string.
And a bit string can, through the wonders of modern CS, be interpreted
as a number. A physical address.
> Bit strings can interpreted in arbitrary ways. One of them is treating
> the bit string as a base 2 integer.
Err yes. I know. Probably better than you.
>
> I'm sure you'll come up again with something stupid to say. Don't let
> me down.
You are an ignorant clown at times.
I showed the code. I showed the results. You can spin it whichever you
want to.
The end result is that the pointer is incremented in
99.99999999999999999% of systems out there initialised or not.
Which part confuses you other than your mad desire to be an anal
retentive fool who can not match the standard to the real world?
> Richard wrote:
> ...
>> 3) In ALL cases I have ever known it IS incremented.
>
> How is that relevant? You clearly do not know ALL cases, since there
Where did I say ALL cases? Please post a link. And it is relevant
because I am telling MY experience.
> are real machines (one has already been cited) where it is NOT
> incremented. The existence of that machine (and many others with
> similar properties) is far more relevant than your lack of experience
> with such machines.
What are you taking about? I never said there were no machines where the
increment DID NOT take place. I countered the argument that was "the
increment will not happen" or words to that affect.
>
>> So to say "it is not incremented" is not true.
>
> No one but you has said anything like that, and you have said it only
> to refute the claim (which no one made). What has been said is that
> your claim that it is incremented is not always true.
Err, I said that. I made it clear maybe 5 times now. I also said I do
not condone sloppy programming which ASSUMES it be so incremented.
>
> ...
>> the standard says, I am merely saying that in the real world in the
>> great majority of cases it is indeed incremented.
>
> And if you had qualified your original statement with "in the great
> majority of cases", it would have been unobjectionable. It was your
> flat out, unqualified assertion that it is incremented that people
> have been objecting to.
I dont recall ever saying that. I said it is incremented on my
machines. I countered that argument which said "it is NOT incremented".
>
>> Which part of the above confuses you or you trying to manipulate this
>> into making me look like some clueless nOOb who is not aware of the
>> dangers of toying with UDB?
>
> You don't look like a clueless nOOb. A nOOb has too little experience,
> and is generally very aware of that fact. You look like someone who
> has too much experience with a limited class of machines, and as a
> result tends to assume that all machines are like the ones you have
> experience with, or at least all machines worth bothering to think
> about.
Unbelievable. Really. Even for c.l.c
> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
<snip>
>> No, but I can see there no point in continuing. We have both made our
>> positions clear.
>
> Actually,no, you haven't. You keep trying to put words in my mouth. I am
> surprised.
It is obvious that I have not been able to clear to you and that you
believe you have not been able to be understood by me. The point is
that I sure that I have been as clear as I want to be and that I have
understood you as well as I can.
> My comments are clear enough.
Then you have nothing to worry about. Everyone will be able to read
what you have said and come to the right conclusion.
--
Ben.
Yes, but I and vippstar suggested using unsigned char because the
pointer pointed to an array of int, so it's safer to use unsigned char
in this cases (I actually asked a question here about this some time
ago).
> 2 (void *) is wrong. You shouldn't write code that only works
> on your compiler, without a special reason.
> There is no special reason here.
>
Surely you meant that performing arithmetic on a (void *) is wrong.
Well, there's at least a small reason here: preference. :-) (Not to
mention the minor annoyance of having to do the conversion.)
Sebastian
Because sometimes you don't need portability and because sometimes
there's a better way?
> > >>>> Besides, void * seems more natural for this kind
> > >>>> of task.
>
> rubbish
>
Why is it rubbish? If you have a void pointer, it will typically point
to any kind of object: int, double, long long, structures, anything.
Does it seem natural to you to treat such an object as if it were a
*character*?
> > >>> "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.
>
> so now you know- so don't do it again
>
Why not? I'll simply keep in mind that it works only under a certain
compiler.
Sebastian
It's helpful in debugging, sometimes. I've never found a
use for it in "deployed" code.
>> readable by scanf to reconstitute that pointer".
>
> Having printed a pointer with %p, how does a program guarantee
> that subsequent printed characters will not undermine scanf's
> ability to reconstitute a comprable pointer value?
That's the same problem one always has: The fact that you've
used printf() and made no mistakes doesn't guarantee that you
can read the same data back again with scanf(). For example,
int i = 42, j = 9;
printf ("%d%d\n", i, j);
Also, FWIW, although I've used "%p" with printf() I have
never found a reason to use it with scanf(). Pleasant symmetry,
I suppose (although printf() and scanf() are by no means mirror
images), but I've never found a use for it.
> If I do something like...
>
> printf("ptr is %p\n", (void *) ptr);
>
> ...what is the guarantee that the output won't exceed an
> implementation's limit on text line width?
None that I can see. But again, the same problem arises
in other situations:
printf("DBL_MAX is %f\n", DBL_MAX);
... might try to print a very long string.
> When I do print pointers, I hex dump the representation.
> It's the only way to gain full control over the output.
> [...]
Well, you can do as you like. It doesn't strike me that
this "full control" you're fond of does you a lot of good, but
if it floats your boat ...
[about incrementing void pointers as opposed to (char *) cast]
> Because sometimes you don't need portability and because sometimes
> there's a better way?
Yes, that better way being the portable way, in this case.
...
> Why is it rubbish? If you have a void pointer, it will typically point
> to any kind of object: int, double, long long, structures, anything.
> Does it seem natural to you to treat such an object as if it were a
> *character*?
No it doesn't. How the heck does void * feel more natural to treat as
a pointer to character than char *?
...
> Why not? I'll simply keep in mind that it works only under a certain
> compiler.
No, what you keep in mind is to never suggest this crap again.
P.S. Just a troll or too stubborn?
No, your original comment did not include the "in most cases"
qualification. You claimed that an uninitialized pointer can be
incremented. Now you've backtracked and qualified your earlier
statement, but you still refuse to admit that your earlier statement
was incorrect. You're even denying ("nothing more. Nothing less.")
that you've changed your statement.
> Chris Dollin <chris....@hp.com> writes:
>
>> Richard wrote:
>>
>>> What pointer do you know that doesnt render as a number? MSDOS,
>>> anything. I have built various SW systems on various machines and am yet
>>> to see a pointer which did not correspond to a memory address.
>>
>> Clearly a pointer has to "correspond" with a "memory address" in some
>> way, otherwise you couldn't use it to access memory.
>>
>>> And lets face it that address IS a number whether you like to be
>>> too clever about it or not.
>>
>> /Part of/ an address has to respect arithmetic, at least + - = < >.
>> That doesn't mean the address /is/ a number. One only has to remember
>> segmented addresses to realise that.
>
> So, you are saying that in segmented architectures (which I wrote
> assembler VGA libraries for) your debugger does not store the pointer
> parts in binary registers which in turn render as numbers on the
> debugger display?
No, I am not saying that. I'm perfectly happy to believe that your
debugger renders bits of pointer as numbers.
> Now this is getting silly.
Correct.
> My only comment was that in most cases an uninitialised pointer will
> indeed increment in the real world.
That's cool, so long as you acknowledge that "most" and don't
confuse it with an "all".
--
'It changed the future .. and it changed us.' /Babylon 5/
Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
> Richard<rgr...@gmail.com> writes:
> [...]
>> My only comment was that in most cases an uninitialised pointer will
>> indeed increment in the real world.
>>
>> nothing more. Nothing less.
> [...]
>
> No, your original comment did not include the "in most cases"
I made it very clear in the thread.
> qualification. You claimed that an uninitialized pointer can be
> incremented. Now you've backtracked and qualified your earlier
I know I did. And I still do. It can be incremented. And in most cases
it will. Is this right to do? No. Seriously, do you not understand what
I am saying here?
> statement, but you still refuse to admit that your earlier statement
> was incorrect. You're even denying ("nothing more. Nothing less.")
> that you've changed your statement.
I have nothing to admit.
I stand by each and every one of my comments.
I can see your agenda here, but sorry it wont wash.
> Richard wrote:
>
>> Chris Dollin <chris....@hp.com> writes:
>>
>>> Richard wrote:
>>>
>>>> What pointer do you know that doesnt render as a number? MSDOS,
>>>> anything. I have built various SW systems on various machines and am yet
>>>> to see a pointer which did not correspond to a memory address.
>>>
>>> Clearly a pointer has to "correspond" with a "memory address" in some
>>> way, otherwise you couldn't use it to access memory.
>>>
>>>> And lets face it that address IS a number whether you like to be
>>>> too clever about it or not.
>>>
>>> /Part of/ an address has to respect arithmetic, at least + - = < >.
>>> That doesn't mean the address /is/ a number. One only has to remember
>>> segmented addresses to realise that.
>>
>> So, you are saying that in segmented architectures (which I wrote
>> assembler VGA libraries for) your debugger does not store the pointer
>> parts in binary registers which in turn render as numbers on the
>> debugger display?
>
> No, I am not saying that. I'm perfectly happy to believe that your
> debugger renders bits of pointer as numbers.
Thats nice. How does your debugger do it? When you look into memory and
you see your pointer stored in an arry how does it look? Hex number by
any chance? What a surprise. If you cast it to a char * and subtract p
from ++p do you get 4 on a 32 bit machine? I did.....
>
>> Now this is getting silly.
>
> Correct.
>
>> My only comment was that in most cases an uninitialised pointer will
>> indeed increment in the real world.
>
> That's cool, so long as you acknowledge that "most" and don't
> confuse it with an "all".
Huh?!?!?!?!
Please quote where I said all. Where I did not qualify with "in my
experience" or "my platforms".
Well, it's a matter of whether you prefer void * or char *.
> ...
>
> > Why is it rubbish? If you have a void pointer, it will typically point
> > to any kind of object: int, double, long long, structures, anything.
> > Does it seem natural to you to treat such an object as if it were a
> > *character*?
>
> No it doesn't. How the heck does void * feel more natural to treat as
> a pointer to character than char *?
>
Read again: I was talking about pointers to int, double, long long,
structures, or any arbitrary object. How do you come up with "pointer
to character"?
> ...
>
> > Why not? I'll simply keep in mind that it works only under a certain
> > compiler.
>
> No, what you keep in mind is to never suggest this crap again.
>
Give me a good argument not to.
> P.S. Just a troll or too stubborn?
You have demonstrated several things in this post:
- You have reading comprehension problems
- You are aggressive about purely stylistic issues
- You are incapable of using decent language
It's clear who is the troll here.
Sebastian
> Richard<rgr...@gmail.com> writes:
>> vipp...@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.
>
I will reply to this to highlight the above statement.
Enough of the stupid games trying to back me into a corner.
Even if that was NOT clear enough, and I can understand that for this NG
it wasnt, I made it perfectly clear later.
It is just as wrong to say "It will NOT increment".
Personally I have never used a machine where it will not increment. Some
of you assure us there are such. I am willing to believe that with no
proof. I have, however, proven that x can increment. With numbers. And
code.
Now, try growing up a little bit and open your mind to the real
world. Its not good pretending it does not exist. It confuses nOObs for
a start. You say "it will not increment" they then see with their own
eyes in the debugger that it does. What do they then think?
The correct statement is
"It is incorrect to increment a non initialised variable since the
behaviour is undefined - however the value may well increment as
expected".
Yes it is. Vippstar is currying favour with the regs. He is obstreperous
to the extreme in his desire to "live and breath the standard".